2013-01-03 28 views
8

我已经看到了一些示例,显示了CycleTile的实际应用,但这些示例都使用了本地图像。一旦应用程序第一次运行并将CycleTile指向远程图像,是否可以设置这些图像?或者如果我确实需要将这些文件保存到手机中,我如何才能让CycleTile引用它们?使用远程图像创建CycleTile

回答

21

CycleTileTemplate & CycleTileData仅支持本地URI和不支持远程Web的URI。这意味着您只能从XAP安装的文件或IsoStore中的文件设置循环映像的来源。

为了支持CycleTileData中的远程图像,您需要在定期后台代理中下载图像,将它们保存到IsoStore,然后使用这些图像更新CycleTileData。推送通知不会在这里工作,因为图像需要是本地的,ShellTileSchedule也不会。

请确保将图像保存到“/ Shared/ShellContent”下的IsoStore中,并将它们的URI设置为“isostore:/Shared/Shellcontent/myImage.png”,否则它们将无法访问开始屏幕图块。

我们来看一个例子。首先,我们写了一个并行线程算法,推出9个下载线程数,等待结果,然后更新的瓷砖开始:

private IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication(); 

private void MainPage_Loaded(object sender, RoutedEventArgs e) 
{ 
     var threadFinishEvents = new List<WaitHandle>(); 

     DownloadImages(threadFinishEvents); 

     new Thread(()=> 
     { 
      Mutex.WaitAll(threadFinishEvents.ToArray()); 

      UpdateTiles(); 

      isoStore.Dispose(); 
     }).Start(); 
} 

接下来,我们将下载9个图像转换成IsoStore“/共享/ ShellContent”。我们将特别注意为每个Web下载添加新的线程标志,并且在文件位于IsoStore中时将标志设置为完成。

private void DownloadImages(List<WaitHandle> threadFinishEvents) 
{ 
    for (int i = 0; i < 9; i++) 
    { 
     var localI = i; 

     var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset); 
     threadFinishEvents.Add(threadFinish); 

     var request = WebRequest.CreateHttp("http://www.justinangel.net/storage/691x336.png"); 
     request.BeginGetResponse(ir => 
     { 
      var result = request.EndGetResponse(ir); 
      using (var isoStoreFile = isoStore.OpenFile("shared/shellcontent/myImage" + localI + ".png", 
                 FileMode.Create, 
                 FileAccess.ReadWrite)) 
      using (var response = result.GetResponseStream()) 
      { 
       var dataBuffer = new byte[1024]; 
       while (response.Read(dataBuffer, 0, dataBuffer.Length) > 0) 
       { 
        isoStoreFile.Write(dataBuffer, 0, dataBuffer.Length); 
       } 
      } 

      threadFinish.Set(); 
     }, null); 
    } 
} 

最后,我们将更新活动切片以使用IsoStore中的新图像。

private void UpdateTiles() 
{ 
    ShellTile.ActiveTiles 
     .First() 
     .Update(new CycleTileData() 
     { 
      Title = "Cyclical", 
      CycleImages = new Uri[] 
      { 
       new Uri("isostore:/Shared/ShellContent/myImage0.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage1.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage2.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage3.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage4.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage5.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage6.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage7.png", UriKind.Absolute), 
       new Uri("isostore:/Shared/ShellContent/myImage8.png", UriKind.Absolute), 
      } 
     }); 
} 

有几个有趣的事情要考虑:

  1. 定期后台代理只需要25秒完成操作,因此激活Mutex.WaitAll时,它可能是有意义的增加计时器thresehold和有它优雅地失败。
  2. 在某些网络条件下,在25秒内下载9张图像可能无法正常工作,因此最好对此进行优化。您可以使用较少的图像,或每30分钟更新一次图像。
  3. 将CycleTileData更新为相同的文件URI不会触发瓦片更新(AFAIK)。所以,你需要更好的文件名,然后myImage0,而是有图像的唯一文件名。
+4

我会建议使用后台文件传输进行下载,非常可靠,而且您不会受限于25秒的限制。 –

+0

matthijs推荐+1。好决定。 – JustinAngel

2

对于CycleTile,图像必须是本地的。您可以设置periodic task以刷新图像,然后将这些图像存储在本地/隔离存储的共享/ shell内容特殊文件夹中(例如,ms-appdata:///local/shared/shellcontent/image01.png)

Session 7 of the Windows Phone 8 Jumpstart是一个很好的参考 - 特别是约25:30在