Chronoir_net.Chronica.WatchfaceExtensionを、実際のWatch Faceアプリのプログラムで使ってみる

By | Date : 2016/12/21 ( Last Update : 2017/01/26 ) | 82 views

本記事は、[初心者さん・学生さん大歓迎!] Xamarin その2 Advent Calendar 2016の21日目の記事です。

前日 : Xamarinを始めてみよう – aodag6 by aodag

明日 : Xamarinハンズオンの感想とxamlを使わないレイアウトの覚書 by aokym

 

こんにちはー!ニアです。

今回は、先日私が作成したライブラリ「Chronoir_net.Chronica.WatchfaceExtension」を、実際のウォッチフェイスアプリのプログラムで使用してみたいと思います。

 

1. 本ライブラリでできること(Ver. 1.0.1の時点)

Chronoir_net.Chronica.WatchfaceExtensionの開発目的は、XamarinでAndroid Wearのウォッチフェイスアプリを開発する時の不便なところを解消し、開発しやすくなるようにサポートすることです。

  1. タイムゾーンやバッテリーの状態などの変更の通知を受け取るために、BroadcastReceiverの派生クラスを一々作成しなくても済むようになります。
  2. Android API 23以降で推奨されているContextCompat.GetColorメソッドの戻り値(int型)から、PaintクラスのColorプロパティで使用するColor型へ簡単に変換できます。
  3. AndroidのTimeクラス、JavaのCalenderクラス、.NETのDateTime構造体のインスタンスを指定するだけで、アナログ時計の時針、分針、秒針の先端のXY座標を簡単に求めることができます。

 

2. Chronoir_net.Chronica.WatchfaceExtensionのインストール

Chronoir_net.Chronica.WatchfaceExtensionはNuGet Galleryで公開しているので、NuGetパッケージマネージャーからインストールします。

検索ボックスに「Chronoir_net.Chronica.WatchfaceExtension」と入力して(※記事執筆時点では、「AndroidWear」でもすぐに見つかります)、検索結果からChronoir_net.Chronica.WatchfaceExtensionを選択し、インストールボタンを押してインストールします。

◆ ライブラリ名変更について

ウォッチフェイスアプリ開発用ツールキットのブランド名の決定に伴い、Chronoir_net.Chronoface.UtilityはChronoir_net.Chronica.WatchfaceExtensionに変更しました。

コード上での変更点は名前空間のみで、クラス名やメソッド名などに変更はありません。

Chronoir_net.Chronoface.Utilityは後日削除予定です。

 

3. Chronoir_net.Chronica.WatchfaceExtensionを使う

今回は、「XamarinでAndroid WearのWatch Faceアプリを作ってみよう!(Vol.2 : プログラム作成編)」( → Gist )で作成したアナログウォッチフェイスで使用してみます。

 

3.1. 名前空間の追加

ソースコードの上部に以下のusingディレクティブを追加します。

 

3.2. タイムゾーン変更通知用のレシーバーの実装をリファクタリング

 

◆ Chronoir_net.Chronica.WatchfaceExtensionを使った、タイムゾーンの変更通知用レシーバーの実装

TimeZoneReceiverクラスの定義と、AnalogWatchFaceEngineのメンバー「timeZoneReceiverRegistered」を削除し、AnalogWatchFaceEngineのメンバー「timeZoneReceiver」の型をTimeZoneReceiverクラスからActionExecutableBroadcastReceiverクラスに変更します。

 

AnalogWatchFaceEngineのコンストラクター及び、OnVisibilityChangedメソッドの「if( timeZoneReceiver == null )」の中で呼び出している、インスタンスの初期化にて、型をTimeZoneReceiverからActionExecutableBroadcastReceiverに変更し、コンストラクターの第2引数に「Intent.ActionTimezoneChanged」を指定します。

 

OnVisibilityChangedメソッドにて、レシーバーのApplication.Contextへの登録及び削除は、ActionExecutableBroadcastReceiverRegisterToContextメソッド及びUnregisterFromContextメソッドを呼び出して行います。

Application.Contextへの登録状態はライブラリの中で判別するので、利用側では単にメソッドを呼ぶだけでOK!

 

変更後のコードを以下に示します。

 

◆ もう1つの方法

ActionExecutableBroadcastReceiverクラスの代わりにEventExecutableBroadcastReceiverクラスで実装するすこともできます。

その場合、BroadcastReceiverのOnReceiveメソッドで呼び出されるデリゲート処理を、BroadcastedIntentRecievedイベントハンドラーに追加します。

 

◆ 他のレシーバーの例

 

3.3. カラーリソースの取得を簡単に

今までは、リソースから色の値を取得する時、CanvasWatchFaceServiceのResources.GetColorメソッドを使用していました。

しかし、Android API 23からそのメソッドは非推奨となり、代わりにAndroid.Support.V4.ContentのContextCompat.GetColorメソッドが推奨されています。

ところが、そのメソッドの戻り値はColor型でなく、ARGB値を格納したint型整数なので、PaintクラスのColorプロパティに直接代入することができません。(運命は残酷だ・・・)

そのため、一旦int型変数に格納し、ビット演算とColor.Argbメソッドを使って、Color型に変換する必要があります。

そこで、WatchfaceUtilityクラスConvertARGBToColorメソッドを利用することで、ARGB値を格納したint型整数をColor型へ簡単に変換することができます。

 

では、OnCreateメソッド内のコードをリファクタリングしてみます。

 

◆ Javaの場合

Javaの場合、PaintクラスのGetColornメソッドの戻り値がColor型、SetColorメソッドの引数がint型と、getとsetで異なる型で設計されていますが、C#の場合、プロパティの仕様上、残念ながらそれができないのです。

SetColorメソッドを独自に追加するという手もありますが、今度はXamarin.Androidのライブラリとしての規則(JavaでGet~/ Set~で対になっているメソッドは、C#ではプロパティで定義する)から外れるという、別の問題が・・・・・・、う~ん、難しいところです。

 

3.3. アナログ時計の針の描画処理をシンプル&簡単に

アナログ時計では、OnDrawメソッド内で、現在時刻から針の角度、先端のXY座標を求め、直線を描画しています。

上記の例では、JavaのCalendarクラスを使用していますが、これを.NETのDateTime構造体に変えるとしましょう。すると、OnDrawメソッド内の彼方此方にあるCalendar.GetメソッドをHour、Minute、Secondプロパティに変更する必要があり、ちょっと面倒ですね。

 

そこで、本ライブラリのAnalogHandStrokeを継承したクラスを利用します。

AnalogWatchFaceEngineのメンバー「hourHandPant」、「minuteHandPant」、「secondHandPant」の型をそれぞれPaintクラスからHourAnalogHandStrokeMinuteAnalogHandStrokeSecondAnalogHandStrokeに変更し、さらに変数名から「Paint」を取り除きます(※今回扱うコードの場合、Visual Studioのリファクタリング機能は利用しません)。

 

OnCreateメソッドにて、Paintクラスの新しいインスタンスを代入している変数の前にvarまたはPaintを追加し、ローカルのPaint型変数にします。

Paintクラスでの初期化処理の後に、先ほどのAnalogHandStrokeの変数を初期化する文を追加し、コンストラクターの引数にPaint型変数をそれぞれ指定します。

 

コンストラクターで指定したPaintクラスのインスタンスは、AnalogHandStorokeのメンバーのPaintプロパティにセットされます。

OnAmbientModeChangedメソッドにあるアンチエリアスの設定処理では、そのPaintプロパティを通して行います。

 

OnDrawメソッドでは、AnalogHandStrokeのLengthプロパティに針の長さをセットし、SetTimeメソッドの引数にCalendarクラス変数を指定して、針の先端のXY座標を求めます。XYプロパティからXY座標、PaintプロパティからPaintクラスのインスタンスを取得し、時針、分針、秒針を描画します。

 

リファクタリング後のコードは、Gistにて公開しています。

 

4. Choroface / Chronicaシリーズの今後のロードマップ

最近、Chronoir.netの新たなプロジェクトして始めた「Chronoface(クロノフェイス)」及び「Chronica(クロニカ)」ですが、今後は、

  • ウォッチフェイスアプリ開発用のテンプレートの作成
  • ウォッチフェイスアプリを作成し、Google Playにリリース

をしていきたいと思います。

テンプレートについては、まず、Wearアプリ単体のプロジェクトテンプレート(※)をリリースし、最終的には設定用のActivityやコンパニオン用のモバイルアプリのひな形、専用のウィザードなどを統合したVSIXパッケージを作っていきたいなと思います。

(※)プロジェクトを作成した時点のコードで、エミュレーターや実機でウォッチフェイスアプリを実行できる形で提供します。2017年1月にリリース予定です。

 

それでは、See you next!

 

この記事をシェアする
Chronoir.netのRSSフィードを購読する

About : ニア(Nia)

紅茶とコーヒーが好きな湘南生まれのプログラマー/ITエンジニアです。主にC#/C++/PHPを使ってプログラミングをしています。趣味は写真撮影と音ゲーです。時々イラストを描いています。プログラミングを勉強している方々と仲良くなりたいです! 興味を持っている分野:UWP/Xamarin/Android Wear/WPF/Windows/Visual Studio/WordPress/KUSANAGI/nginx

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*