如何在Windows Phone 8.1中每分钟更新一次自定义图像Live Tile?

时间:2014-06-28 13:26:17

标签: windows-runtime windows-phone windows-phone-8.1 live-tile

有很多Windows Phone 8.1应用程序(例如时钟集线器,模拟时钟平铺等),可以在主屏幕上固定模拟时钟。

我正在尝试按照此sample执行相同的操作,它向我展示了如何每分钟更新XML文档。

但如果我要创建一个模拟时钟磁贴,那么它需要是一个图像。

我尝试将XamlRenderingBackgroundTaskRenderTargetBitmap一起使用来生成图片,此位有效。我不知道如何每分钟更新此图像。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:3)

我拍摄了您提供的样本并对其进行了修改,以便每分钟生成一个自定义图像动态图块。

我已经在手机上测试了它,似乎工作正常。您可能需要进行更多测试,例如内存使用测试,以确保它不会超过上限(可能会将planTill减少到30分钟以在循环中生成更少的磁贴?)。

UserControl xml文件SquareFrontTile1.xml

<Border Height="360" Width="360" Background="#00b2f0" xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006'>
  <TextBlock Text="{0}" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="White" FontSize="50.667" />
</Border>

代码

public static async void UpdateAsync(BackgroundTaskDeferral deferral)
{
    TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForApplication();
    IReadOnlyList<ScheduledTileNotification> plannedUpdated = tileUpdater.GetScheduledTileNotifications();

    string language = GlobalizationPreferences.Languages.First();
    CultureInfo cultureInfo = new CultureInfo(language);

    DateTime now = DateTime.Now;
    DateTime planTill = now.AddHours(1);

    DateTime updateTime = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, 0).AddMinutes(1);
    if (plannedUpdated.Count > 0)
        updateTime = plannedUpdated.Select(x => x.DeliveryTime.DateTime).Union(new[] { updateTime }).Max();

    StorageFolder folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets");
    StorageFile file = await folder.GetFileAsync("SquareFrontTile1.xml");
    string xml = await Windows.Storage.FileIO.ReadTextAsync(file);
    string startXml = string.Format(xml, now.ToString(cultureInfo.DateTimeFormat.ShortTimePattern));

    XmlDocument tileDocumentNow = await GetTileXmlDocument(startXml);

    TileNotification notification = new TileNotification(tileDocumentNow) { ExpirationTime = now.AddMinutes(1) };
    tileUpdater.Update(notification);

    for (var startPlanning = updateTime; startPlanning < planTill; startPlanning = startPlanning.AddMinutes(1))
    {
        Debug.WriteLine(startPlanning);
        Debug.WriteLine(planTill);

        try
        {
            string updateXml = string.Format(xml, startPlanning.ToString(cultureInfo.DateTimeFormat.ShortTimePattern));
            XmlDocument updatedTileDocument = await GetTileXmlDocument(updateXml);

            ScheduledTileNotification scheduledNotification = new ScheduledTileNotification(updatedTileDocument, new DateTimeOffset(startPlanning)) { ExpirationTime = startPlanning.AddMinutes(1) };
            tileUpdater.AddToSchedule(scheduledNotification);

            Debug.WriteLine("schedule for: " + startPlanning);
        }
        catch (Exception e)
        {
            Debug.WriteLine("exception: " + e.Message);
        }
    }

    deferral.Complete();
}

private static async Task<XmlDocument> GetTileXmlDocument(string xml)
{
    Border tileUIElement = XamlReader.Load(xml) as Border;
    string liveTileImageName = string.Format("UpdatedLiveTile_{0}.png", DateTime.Now.Ticks.ToString());

    if (tileUIElement != null)
    {
        RenderTargetBitmap rtb = new RenderTargetBitmap();
        await rtb.RenderAsync(tileUIElement, 150, 150);
        IBuffer pixels = await rtb.GetPixelsAsync();
        DataReader dReader = Windows.Storage.Streams.DataReader.FromBuffer(pixels);
        byte[] data = new byte[pixels.Length];
        dReader.ReadBytes(data);

        var outputFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.CreateFileAsync(liveTileImageName, Windows.Storage.CreationCollisionOption.ReplaceExisting);
        var outputStream = await outputFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
        BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, outputStream);
        enc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, 150, 150, 96, 96, data);
        await enc.FlushAsync();
    }

    var tileDocument = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Image);
    var tileImageAttributes = tileDocument.GetElementsByTagName("image");
    XmlElement tmp = tileImageAttributes[0] as XmlElement;
    tmp.SetAttribute("src", liveTileImageName);
    return tileDocument;
}

答案 1 :(得分:1)

我不会完全回答这个问题,因为我本人正试图让这项工作在目前。但是我会让你朝着正确的方向前进。我以前用Windows 8做过这个。

您需要做的是创建平铺更新程序并经常安排平铺更新...在这种情况下每分钟一次。选择的图块模式可以是图像或文本或两者的组合。

您可以在此处找到TileSchema目录 http://msdn.microsoft.com/en-us/library/windows/apps/hh761491.aspx

以及Tile Schema的详细信息 http://msdn.microsoft.com/en-us/library/windows/apps/br212859.aspx

这是一个Windows 8示例 http://code.msdn.microsoft.com/windowsapps/scheduled-notifications-da477093

以下是我的代码中的代码段,到目前为止无法正常工作... tile是空白

TileUpdater updater = TileUpdateManager.CreateTileUpdaterForApplication();
XmlDocument document = new XmlDocument();
document.LoadXml(str2);
ScheduledTileNotification notification2 = new ScheduledTileNotification(document, new DateTimeOffset(time4));
notification2.ExpirationTime = (new DateTimeOffset?((DateTimeOffset)time4.AddMinutes(1.0)));
ScheduledTileNotification notification = notification2;
updater.AddToSchedule(notification);

完成此操作后,我会写一篇博文并在此处添加链接

我创建了一个repro项目,试图从示例应用程序(而不是后台任务)中执行此操作。 http://1drv.ms/1nai8nn

答案 2 :(得分:-1)

示例适用于我,我添加到Windows Phone Silverlight 8.1。您必须在WMAppManifest.xml中将Notification Services从MPN更改为WNS,并在Package.appxmanifest(声明选项卡)中添加后台任务,勾选系统事件,计时器。

@Justin XL:你的代码对我不起作用,行错误

Border tileUIElement = XamlReader.Load(xml) as Border;

错误:应用程序调用了为不同线程编组的接口。