使用后台任务更新动态磁贴

重要的 API

使用后台任务将应用的动态磁贴更新为最新内容。

下面是演示如何向应用添加动态磁贴的视频。

创建后台任务项目

要为应用启用动态磁贴,请向你的解决方案中添加一个新的 Windows 运行时组件项目。 这是一个单独的程序集,当用户安装应用时,OS 会在后台加载并运行。

  1. 在解决方案资源管理器中,右键单击解决方案,单击“添加”,并单击“新建项目”
  2. “添加新项目”对话框中,选择“已安装>的>其他语言 Visual C# > Windows 通用”部分中的Windows 运行时组件模板
  3. 将项目命名为 BackgroundTasks,然后单击或点击“ 确定”。 Microsoft Visual Studio 将新项目添加到解决方案。
  4. 在主项目中,添加对 BackgroundTasks 项目的引用。

实施后台任务

实现 IBackgroundTask 接口以创建更新应用的动态磁贴的类。 后台工作将进入 Run 方法。 在这种情况下,任务会获取 MSDN 博客的联合源。 若要防止任务在异步代码仍在运行时过早关闭,请获取延迟。

  1. 在解决方案资源管理器中,将自动生成的文件Class1.cs重命名为BlogFeedBackgroundTask.cs。
  2. 在BlogFeedBackgroundTask.cs中,将自动生成的代码替换为 BlogFeedBackgroundTask 类的存根代码。
  3. 在 Run 方法实现中,添加 GetMSDNBlogFeed 和 UpdateTile 方法的代码
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// Added during quickstart
using Windows.ApplicationModel.Background;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Windows.Web.Syndication;

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

            // Download the feed.
            var feed = await GetMSDNBlogFeed();

            // Update the live tile with the feed items.
            UpdateTile( feed );

            // Inform the system that the task is finished.
            deferral.Complete();
        }

        private static async Task<SyndicationFeed> GetMSDNBlogFeed()
        {
            SyndicationFeed feed = null;

            try
            {
                // Create a syndication client that downloads the feed.  
                SyndicationClient client = new SyndicationClient();
                client.BypassCacheOnRetrieve = true;
                client.SetRequestHeader( customHeaderName, customHeaderValue );

                // Download the feed.
                feed = await client.RetrieveFeedAsync( new Uri( feedUrl ) );
            }
            catch( Exception ex )
            {
                Debug.WriteLine( ex.ToString() );
            }

            return feed;
        }

        private static void UpdateTile( SyndicationFeed feed )
        {
            // Create a tile update manager for the specified syndication feed.
            var updater = TileUpdateManager.CreateTileUpdaterForApplication();
            updater.EnableNotificationQueue( true );
            updater.Clear();

            // Keep track of the number feed items that get tile notifications.
            int itemCount = 0;

            // Create a tile notification for each feed item.
            foreach( var item in feed.Items )
            {
                XmlDocument tileXml = TileUpdateManager.GetTemplateContent( TileTemplateType.TileWide310x150Text03 );

                var title = item.Title;
                string titleText = title.Text == null ? String.Empty : title.Text;
                tileXml.GetElementsByTagName( textElementName )[0].InnerText = titleText;

                // Create a new tile notification.
                updater.Update( new TileNotification( tileXml ) );

                // Don't create more than 5 notifications.
                if( itemCount++ > 5 ) break;
            }
        }

        // Although most HTTP servers do not require User-Agent header, others will reject the request or return
        // a different response if this header is missing. Use SetRequestHeader() to add custom headers.
        static string customHeaderName = "User-Agent";
        static string customHeaderValue = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";

        static string textElementName = "text";
        static string feedUrl = @"http://blogs.msdn.com/b/MainFeed.aspx?Type=BlogsOnly";
    }
}

设置包清单

若要设置包清单,请打开它并添加新的后台任务声明。 将任务的入口点设置为类名,包括其命名空间。

  1. 在解决方案资源管理器中,打开 Package.appxmanifest。
  2. 单击或点击“ 声明 ”选项卡。
  3. 在“可用声明”下,选择 BackgroundTasks,然后单击“添加”。 Visual Studio 在“支持的声明”下添加 BackgroundTasks
  4. 在“支持的任务类型”下,确保检查计时器
  5. 在“应用设置”,将入口点设置为 BackgroundTasks.BlogFeedBackgroundTask
  6. 单击或点击 “应用程序 UI ”选项卡。
  7. 将锁屏界面通知设置为锁屏提醒和磁贴文本
  8. 在锁屏提醒徽标字段中设置 24x24 像素图标的路径。 重要说明 此图标必须仅使用单色和透明像素。
  9. “小徽标 ”字段中,将路径设置为 30x30 像素图标。
  10. Wide 徽标 字段中,将路径设置为 310x150 像素图标。

注册后台任务

创建 BackgroundTaskBuilder 以注册任务。

注意 ,从 Windows 8.1 开始,在注册时验证后台任务注册参数。 如果有任何注册参数无效,则会返回一个错误。 你的应用必须能够处理后台任务注册失败的情况-例如,使用条件语句检查注册错误,然后使用不同的参数值重试失败的注册。  

在应用的主页中,添加 RegisterBackgroundTask 方法,并在 OnNavigatedTo 事件处理程序中调用该方法。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using Windows.Data.Xml.Dom;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Syndication;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/p/?LinkID=234238

namespace ContosoApp
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo( NavigationEventArgs e )
        {
            this.RegisterBackgroundTask();
        }


        private async void RegisterBackgroundTask()
        {
            var backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
            if( backgroundAccessStatus == BackgroundAccessStatus.AllowedSubjectToSystemPolicy ||
                backgroundAccessStatus == BackgroundAccessStatus.AlwaysAllowed )
            {
                foreach( var task in BackgroundTaskRegistration.AllTasks )
                {
                    if( task.Value.Name == taskName )
                    {
                        task.Value.Unregister( true );
                    }
                }

                BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
                taskBuilder.Name = taskName;
                taskBuilder.TaskEntryPoint = taskEntryPoint;
                taskBuilder.SetTrigger( new TimeTrigger( 15, false ) );
                var registration = taskBuilder.Register();
            }
        }

        private const string taskName = "BlogFeedBackgroundTask";
        private const string taskEntryPoint = "BackgroundTasks.BlogFeedBackgroundTask";
    }
}

调试后台任务

若要调试后台任务,请在任务的 Run 方法中设置断点。 在 “调试位置” 工具栏中,选择后台任务。 这会导致系统立即调用 Run 方法。

  1. 在任务的 Run 方法中设置断点。
  2. 按 F5 或点击 “调试 > 开始调试 ”以部署并运行应用。
  3. 应用启动后,切换回 Visual Studio。
  4. 确保 “调试位置” 工具栏可见。 它位于 “视图 > 工具栏” 菜单上。
  5. “调试位置”工具栏上,单击“暂停”下拉列表,然后选择 BlogFeedBackgroundTask
  6. Visual Studio 在断点处暂停执行。
  7. 按 F5 或点击“调试继续”>继续运行应用。
  8. 按 Shift+F5 或点击“ 调试 > 停止调试 ”以停止调试。
  9. 返回到“开始”屏幕上的应用磁贴。 几秒钟后,磁贴通知将显示在应用的磁贴上。