バックグラウンドエージェントでのライブタイルの更新



私の意見では、Windows Phoneの長所の1つはその設計です。 より正確には、開発者がアプリケーションの開発を最大限に活用するために使用できる設計コンセプト。



重要な概念の1つは、ライブタイルまたは「ライブタイル」-「ステロイドのアプリケーションアイコン」です。 Live Tilesを適切に使用すると、ユーザーがアプリケーションにバインドされ、使用時にまったく異なるエクスペリエンスが提供されます。 たとえば、天気予報用のアプリケーションを選択したときの重要な基準は、アプリケーションにライブタイルがあり、天気予報をすばやく更新することでした。 その結果、アプリケーションをセットアップし、開始画面でライブタイルを修正した後、私はこのアプリケーションをほとんど起動しませんでしたが、同時に、ロック画面を削除した直後に、運用気象情報が表示されます。



良い例だと思いますが、これをどのように行うのでしょうか?





使用するアプリケーションは、定期的なバックグラウンドエージェントを使用して、ライブタイルを更新します(複数の都市にライブタイルを固定できるため、複数存在する場合があります)。



バックグラウンドエージェントからライブタイル更新を実装する方法の例を見てみましょう。



最初に、タイル用に2つの背景画像を準備します。 私は次のことをしました:



そして



これらは、透明な背景にサイズが173x173のPNGファイルであるため、携帯電話に現在インストールされているテーマの色の下敷きが見えるようになっています。



次に、C#でWindows Phoneアプリケーションに基づいた単純なプロジェクトを作成します。 準備した写真を追加します。 それらを単純な名前1.pngおよび2.pngで追加しました。 設定では、コンテンツタイプとコピー条件を設定する必要があります。



アプリケーションの開発に直接進みます。



メインアプリケーションタイルと1つのセカンダリタイルを更新します。



注:アプリケーションは、開始画面に固定されていなくても、常にアプリケーションタイルを持っています。 複数のセカンダリタイルが存在する可能性があるため、アプリケーションから作成する必要があります。



2番目のページをアプリケーションに追加し、LandingPage.xamlと呼びます。アプリケーションの2番目のタイルをクリックすると開きます。



MainPage.xamlアプリケーションのメインページに移動して、ボタンを追加します。

<!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="LIVE TILES UPDATE DEMO" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel> <Button Height="100" Content="  " Name="TileAdder" Click="TileAdder_Click"></Button> </StackPanel> </Grid>
      
      







ボタンクリックハンドラーをコードに追加し、特定の「デモロジック」を含むセカンダリタイルを追加します。

 private void TileAdder_Click(object sender, RoutedEventArgs e) { IsolatedStorageFile CounterStorage = IsolatedStorageFile.GetUserStoreForApplication(); IsolatedStorageFileStream CounterStream = CounterStorage.OpenFile("counter", System.IO.FileMode.OpenOrCreate); int count = CounterStream.ReadByte(); if (count < 0) count = 1; StandardTileData appTileData = new StandardTileData(); if ((count % 2) == 0) { appTileData.Title = " 002"; appTileData.BackgroundImage = new Uri("/1.png", UriKind.RelativeOrAbsolute); } else if ((count % 7) == 0) { appTileData.Title = " 007"; appTileData.BackgroundImage = new Uri("", UriKind.RelativeOrAbsolute); } else { appTileData.Title = " 000"; appTileData.BackgroundImage = new Uri("/2.png", UriKind.RelativeOrAbsolute); } appTileData.Count = count; CounterStream.Seek(0, SeekOrigin.Begin); count = count + 5; if (count > 99) count = 99; CounterStream.WriteByte((byte)count); CounterStream.Close(); ShellTile.Create(new Uri("/LandingPage.xaml", UriKind.RelativeOrAbsolute), appTileData); }
      
      







セカンダリタイルを作成するには、まずタイルデータを含むオブジェクトを作成してから、呼び出されるページのURIとデータを含むオブジェクトを渡すメソッドを呼び出します。すべてが非常に簡単です。



セカンダリタイルのコンテンツを変更するためのロジックは、アプリケーションのデモンストレーション時に異なるパラメーターでタイルを作成するように設計されています。



動的に変化するカウンタを持つファイルの使用に注意してください。これは、外部データの受信の模倣またはアプリケーションとバックグラウンドエージェント間の同期のデモです。



Countプロパティが99より大きい場合でも99が表示されるため、99までカウントするだけで、intからbyteに簡単に変換できます。



次に、タイルのデータを更新するバックグラウンドエージェントを作成する必要があります。 ソリューションにWindows Phoneスケジューラタスクエージェントのようなプロジェクトを追加してから、メインプロジェクトにリンクを追加し、その名前空間をメインアプリケーションのメインページのブロックを使用して追加しましょう。



また、aspenアプリケーションのメインページのusingブロックでは、分離ストレージとエージェントを操作するために名前空間を追加することを忘れないでください。 プロジェクトにUpdateTileAgentという名前を付けました。私の場合、このブロックは次のようになります。

 using UpdateTileAgent; using Microsoft.Phone.Scheduler; using System.IO.IsolatedStorage; using System.IO;
      
      







そのため、バックグラウンドエージェントを作成して登録する必要があります。 これは、メインページのLoadedイベントハンドラーで行います。 これを行うには、このハンドラーを追加し、エージェント作成コードをハンドラーに追加します。

 const string UpdateTileAgentName = "Agent-Tile"; // Constructor public MainPage() { InitializeComponent(); this.Loaded += new RoutedEventHandler(MainPage_Loaded); } void MainPage_Loaded(object sender, RoutedEventArgs e) { PeriodicTask myPeriodicTask = ScheduledActionService.Find(UpdateTileAgentName) as PeriodicTask; if (myPeriodicTask != null) { try { ScheduledActionService.Remove(UpdateTileAgentName); } catch (Exception ex) { MessageBox.Show("    :" + ex.Message); } } myPeriodicTask = new PeriodicTask(UpdateTileAgentName); myPeriodicTask.Description = "Agent-Tile"; try { ScheduledActionService.Add(myPeriodicTask); #if DEBUG ScheduledActionService.LaunchForTest(UpdateTileAgentName, TimeSpan.FromSeconds(10)); #endif } catch (Exception ex) { MessageBox.Show("  :" + ex.Message); } if (ShellTile.ActiveTiles.Count() > 1) TileAdder.IsEnabled = false; }
      
      







一般に、コードは非常に単純です。 いくつかの機能に注意を払いたいです。



定期的なエージェントは30分ごとに実行されます。 これはデバッグにはあまり便利ではないため、デバッグアセンブリでは10秒後にエージェントを起動するように要求する条件付きコンパイルディレクティブを使用します。

 #if DEBUG ScheduledActionService.LaunchForTest(UpdateTileAgentName, TimeSpan.FromSeconds(10)); #endif
      
      







同じページへのリンクを含む複数のセカンダリタイルを作成したくありません。 したがって、タイルの数を確認し、これに応じて、タイルを追加するためのボタンをオン/オフにします。

 if (ShellTile.ActiveTiles.Count() > 1) TileAdder.IsEnabled = false;
      
      





エージェントの説明フィールドは必須であり、それがないとスケジューラーに追加されません。



アプリケーション自体ですべてが完了しました。 これで、エージェントに進むことができます。



エージェントの主な作業は、 OnInvokeメソッドで実行されます。

  protected override void OnInvoke(ScheduledTask task)
      
      







タイルを使いやすくするために、エージェントコードブロックの使用に必要なディレクティブを追加することを忘れないでください。 私にとっては次のようになります。

 using System; using System.Collections.Generic; using System.Linq; using System.Windows; using Microsoft.Phone.Scheduler; using Microsoft.Phone.Shell; using System.IO.IsolatedStorage; using System.IO;
      
      







カウンター形式の「外部」データに基づいてエージェントコードにタイルの更新を追加し、セカンダリタイルを作成するためのロジックと同様のロジックを使用して、さまざまなものを追加します。



タイル更新コードを別の関数として割り当てました。

 void TileUpdater(ShellTile tile, int count) { StandardTileData appTileData = new StandardTileData(); if ((count % 2) == 0) { appTileData.Title = " 002"; appTileData.BackgroundImage = new Uri("/1.png", UriKind.RelativeOrAbsolute); } else if ((count % 7) == 0) { appTileData.Title = " 007"; appTileData.BackgroundImage = new Uri("", UriKind.RelativeOrAbsolute); } else { appTileData.Title = " 000"; appTileData.BackgroundImage = new Uri("/2.png", UriKind.RelativeOrAbsolute); } appTileData.Count = count+1; tile.Update(appTileData); }
      
      







OnInvokeメソッド自体は次のようになります。

 protected override void OnInvoke(ScheduledTask task) { ShellTile AppTile = ShellTile.ActiveTiles.FirstOrDefault(); IsolatedStorageFile CounterStorage = IsolatedStorageFile.GetUserStoreForApplication(); IsolatedStorageFileStream CounterStream = CounterStorage.OpenFile("counter", System.IO.FileMode.OpenOrCreate); int count = CounterStream.ReadByte(); if (count < 0) count = 1; //     TileUpdater(AppTile, count+1); //       if (ShellTile.ActiveTiles.Count() > 1) { //  -    IEnumerable<ShellTile> tiles = ShellTile.ActiveTiles.Skip(1); //   Secondary Tiles foreach (ShellTile st in tiles) { TileUpdater(st, count); } } CounterStream.Seek(0, SeekOrigin.Begin); count++; if (count > 99) count = 99; CounterStream.WriteByte((byte)count); CounterStream.Close(); #if DEBUG ScheduledActionService.LaunchForTest(UpdateTileAgentName, TimeSpan.FromSeconds(10)); #endif NotifyComplete(); }
      
      







ここで何が見えますか? すでによく知っているリクエストは、10秒後にエージェントを起動し、メインアプリケーションタイルと追加のタイルを更新するための共有ロジックです。 アプリケーションタイルはリストの最初にあり、アプリケーションが開始画面で固定されていない場合でも常にそこにあるため、これを実装できることを思い出してください。



ここで、エージェントの他のタイルプロパティを更新することもできます。 タイルとプロパティの詳細については、 http//msdn.microsoft.com/en-us/windowsphone/hh505822をご覧ください



これで、エミュレータでアプリケーションをビルドして実行できます。 スタート画面でアプリケーションを修正し、2番目のタイルを作成することを忘れないでください。 時間の経過とともにタイルがどのように変化するかを確認してください。



この知識を身に付けた今、Windows Phoneアプリケーションに高度なLive Tiles機能を簡単に追加できると思います。



UPD :通知してくれたmax_sokolovに感謝します。 定期的に起動するバックグラウンドエージェントには、次のプロパティがあります。

便利なリンク:

MSDNのWindows Phone開発センター

Windows Phone SDK 7.1

ロシア語でのWindows Phone開発フォーラム



All Articles