2013-01-03 27 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在