2014年9月28日日曜日

ごみ出しカレンダー を公開しました


ごみ出しカレンダー
Windows 8.1 / Windows Phone 8.1 で動作します

ストアアプリ 「ごみ出しカレンダー」を公開しました。
 Windows 8.1 / Windows Phone 8.1 でお使い頂ける Universal Windows App になっています。無料です。

Windows ストア からダウンロード
Windows Phone ストアからダウンロード

ごみ出しカレンダー で できる事


  • ごみ出し専用のカレンダー アプリです。
  • アプリ上で入力した曜日毎のごみ分別情報を、スタート画面上のタイルに表示します。
  • 同じMicrosoft アカウント を使用しているWindows / Windows Phone 上で同じごみ出しデータを共有します。例えば、Desktop・TabletでWin8.1、スマホはWindows Phone 8.1を使っているハワイ在住のAさんの場合、どれか一つでごみ出しデータを更新すると、数分~数十分で他のSystem でも同じデータが表示されるようになります。

スタート画面上のタイル表示


…今回のアプリ、技術的にやっていることは気絶するほど単純ですし、また機能的にも…OS標準のカレンダーで別にいいんじゃん?と言われると全くその通りです。

(OS標準カレンダーの貴重なスペースを、Weeklyなゴミ出し予定で埋めたくないという所はあり、そこは便利とは思うのですが)

では何で作ったかというと、Windows / Windows Phone で多くのCodeを共有できるUniversal Windows App の作成を頭からお尻まで通して行っておきたい、という学習目的です。
futa8 も、今作っているPICT8 も、Code baseはそこそこ大きいサイズなので…気軽に色々ひょいと試せる感じでは無くなっており、Universal App化のようなChallengeを気軽に試せるものを作っておきたかったというのも大きいです。

...

実際、実アプリとして書いてみることで収穫は多かったです。

正直な所、Universal Appっつっても同じBinary動く訳では無いし…と若干引いて見ている所が僕にはあったのですが、実際やってみると所謂Data Source側では気を付けて書く事でかなりそのままいけるなぁと。

UIはそのままとは行かないのですが、WinRT のUI コンポーネントの互換性はかなり高いので、例えばメイン画面の月別カレンダー作るところ等はサイズを変えている以外、Code BehindもXAMLも全く同じCodeになっています。編集ページもサイズ変更だけでほぼそのままです。

逆に、共用できないXAML部分をなるべくコピペで済ませるために、サイズ部分をなるべくStyleで外に出しておく的な(ダメな?当たり前?)知識も身につきました。

反面、Template Defaultでの各Pageの遷移、Instance化ではWinとWPでは違うところも多く、うお何これ!?という所も多かったです。

手を動かすと経験値上がるな!という当たり前の話を噛み締めているところです。



StoreApp で位置情報を扱う

この項では、
  1. 位置情報を取得する
  2. 位置情報を住所の文字列に変換する
方法について書きます。

1. 位置情報の取得


現在の位置情報を取得


Namespace Windows.Devices.Geolocation にあるGeolocator Class を使います。

 

// Appの初期化の辺りで一発Geolocatorを作成しておき、
this.geolocator = new Geolocator();
...
// 位置情報が必要な時にGetGeopositionAsyncを呼ぶ。
var pos = await this.geolocator.GetGeopositionAsync();

ここで要注意なのは、
  1. 位置情報を取得するアプリは、AppxManifest.xml内で位置情報の使用を宣言する必要があること
  2. 起動後初回の使用では「位置情報の取得」の確認メッセージが出ること
  3. GetGeopositionAsync では緯度経度のみが取得でき、住所データは取得出来ない事(今のところ)
1. については、VSのManifest Designerでチェックを入れるだけです。又、ストア上にはこのアプリが位置情報を使用する旨が表示されます。

2. これはAPIをCallしたところ(上の例だとGetGeopositionAsync)で問答無用に表示されます。
このため、なるべく、Userの操作の結果(ボタン押下のハンドラ等)…「○○をやろうとした結果」として呼ばれるところでAPIをCallすべきと思います。
Userの操作の無い所…初期化中等…でいきなりこれを出すのはあまり上品では無いように思います。そういうアプリたまに見ますが。

3. GetPositionAsync の返り値 として帰るGeoposition Classには以下二つのProperty…
  • CivicAddress
  • Coordinate
があり、前者には住所文字列、後者には緯度経度が入る、事になっています。
が、前者CivicAddressは、Address Provider、緯度経度を住所に変換するプロバイダがインストールされていない場合常に空文字列で返ります。
そして、現在のところAddress Providerは何処からも提供されていないです。

画像の位置情報を取得


JPEG画像にEXIF データとして位置情報が埋め込まれている場合があります。
これは大変に簡単で、画像ファイルのStorageFileからImagePropertiesを取得します。もし緯度経度データが存在すれば、ImageProperties.LatitudeとLongitudeにデータが詰まっています。

※ 画像が「ファイル」である場合…Storage上のFileにはこれでいけるのですが…例えば、一度OpenFileAsyncしてStreamに全部ガーっと呼んだメモリ上のデータや、Httpか何かでがーっとDLしてまだファイルに落として無いデータ、に対して使用することは出来ないです。困った。


2. 位置情報を住所文字列に変換する


上で触れたようにWinRT組み込みのGeolocator Classだけでは不可能で、Bing.Maps APIを使う事になります。
緯度経度をAPI経由でBingに投げると、住所に変換して返してくれるという感じです。

Bing APIの使用には
  • アカウント登録とAPI Keyの作成
  • Bing Maps SDKのインストールと参照の追加
が必要になります。方法はMSのサイトでも見て頂ければいいのですが、無料の場合、
  • キーは3つまで
  • 50,000 Transaction/Day
となっています。間違えていると怖いのでご自分でご確認下さい。

※ Bing Maps API は Architecture毎のNative BinaryとしてBuildされています。このため、このAPIを「使う」Moduleは(.NETで書いたC#であっても)「Any CPU」としてBuildすることが出来なくなります。

Bing Maps API を使用した住所の取得


ここまで行くとソース見たほうが早いべ、という事でソースを貼って終わります。
注意点としては、LocationData は複数返ってくるので、中の属性を見て必要なものだけ拾う、という所です。

※ 以下の例は、アプリ「ごみ出しカレンダー」で使っているCodeです。
ごみ種別の入力画面でアプリバー上の「検索」ボタンを押すと、PCの現在地を使ってごみ収集ページを検索してあげる、という機能です。(自治体ごとに千差万別のごみ出しページをスクレイピングとかやってられないので、そこから先は手動です)

ごみ出しカレンダー
http://apps.microsoft.com/windows/app/c3cdaa23-5b99-4b28-803f-00b90c86a601


 
private async void GetAddressAppBarButton_Click(object sender, RoutedEventArgs e)
        {
             //「PCの位置情報から自治体のごみ出しページを検索してあげる」

            var loader = new Windows.ApplicationModel.Resources.ResourceLoader();

            var pos = await this.geolocator.GetGeopositionAsync();
            
            Bing.Maps.Search.ReverseGeocodeRequestOptions requestOptions =
                new Bing.Maps.Search.ReverseGeocodeRequestOptions(new Location(pos.Coordinate.Point.Position.Latitude, pos.Coordinate.Point.Position.Longitude));

            var searchManager = this.bingMaps.SearchManager;
            var response = await searchManager.ReverseGeocodeAsync(requestOptions);

            string query = "";
            Bing.Maps.Search.GeocodeAddress addr = null;

            if (null != response && 0 < response.LocationData.Count)
            {
                for (int i = 0; i < response.LocationData.Count; i++)
                {
                    /// 住所表示に使うLocationDataを探すCode
                    /// Bing.Mapsでは、Responseに複数のLocationDataが詰まって返ってくることがある。(普通は一個だが、たまに二つ)
                    /// 一つは地図上での住所表示用データ ... GeocodeLocationUsageType 'Display'
                    /// もう一つはナビ用の道路情報。 ... GeocodeLocationUsageType 'Route' または 'Both'.
                    /// 後者については住所の文字列が入っていないので、今回は必要が無いデータとなる。それを弾いて住所表示用だけをPickする。
                    /// (後者は大体Nameに「MajorRoad」とかが入ってる)

                    if (null != response.LocationData[i].GeocodeLocations && 0 < response.LocationData[i].GeocodeLocations.Count)
                    {
                        if (Bing.Maps.Search.GeocodeLocationUsageType.Display == response.LocationData[i].GeocodeLocations[0].UsageType)
                        {
                            /// 'Display'が複数ある場合は… 知らないし 最初の一つだけPickする
                            addr = response.LocationData[i].Address;
                            break;
                        }
                    }
                }

                if( null != addr )
                {
                    /// StrWebQuery ... "ごみ+収集日+"
                    /// AdminDistrict ... "神奈川県" 大体県まで
                    /// AdminDistrict2 ... データ見たこと無いのだけど 郡とか?
                    /// Locality ... "川崎市高津区" 大体市+区まで
                    /// AddressLine ... "foo町bar丁目1-2-3" 最後のアドレス ごみ収集日検索では却って結果出なくなるので使わない
                    
                    query = loader.GetString("StrWebQuery"); 
                    if( 0 < addr.AdminDistrict.Count() ) query += (addr.AdminDistrict + "+");
                    if( 0 < addr.AdminDistrict2.Count() ) query += (addr.AdminDistrict2 + "+");
                    if( 0 < addr.Locality.Count() ) query += (addr.Locality );
                }

                // URL形式にエンコ %1234...みたいなやつ
                query = System.Net.WebUtility.UrlEncode(query);

                // ブラウザ起動
                await Windows.System.Launcher.LaunchUriAsync(new Uri( "http://www.google.com/search?q=" + query));
            }
            else
            {
                // 何もすることが無い
                // Errormsgも出さなくていいかなと
            }
        }
    }








2014年8月26日火曜日

PICT8

( PICT8 は 2014年12月にリリースされました。Windows ストア からダウンロードできます。)

PICT8 とは


軽快な動作の画像ファイル閲覧と、Zip/Pdf 見開き表示が出来る画像ビュアーです。
Windows ストアでの販売(売り切り、広告無し)を予定しています。
※開発中

軽快な画像ファイル閲覧

素早い画像サムネイル表示と、左右スワイプでの画像切り替え。
先読みキャッシュと多段階デコードで軽快な画像ブラウズを行うことができます。
アニメーションGIFを表示できます。
既定ではピクチャ ライブラリが閲覧可能で、適宜任意(ローカル フォルダ、OneDrive、ネットワークドライブ、ホームネットワーク…)のフォルダを追加できます。

片手での操作を追究したブックモード

「片手フリーな状態で本を読みたい」これはPICT8 開発の最大の理由でもあります。
手の大きさ・タブレットのサイズにも寄る所は大きいのですが、片手でタブを掴んだまま指一本で操作するためのCommander UI を搭載しています。

Commander UI とは?

ページ送り・戻し、注目点移動/スクロール、次の本・前の本へ移動…を小さくまとめたものです。
タブレットを片手で掴んだ状態で、親指・人差し指等で操作が可能です。
Commander UIは画面の何処にでも置くことができ、またサイズ・角度も変更できます。

またマウス操作でも、操作の範囲が小面積で収まるCommander UIはフローティングツールバーのように便利にお使い頂けます。

ブックモードは、Zip・PDF・フォルダ に対応しています。
既定ではタブレット横位置で両開き、縦位置で1P表示です。

他のストアアプリからも使えます

Windows 8/8.1のストアアプリで画像を開く場合、普通はOS標準のファイル ピッカーを使うのですが…

・ファイル名が表示されない場合がある
・画像サイズ・撮影日等がわからない場合がある
・サムネイルが小さすぎて何が映ってるのかわからない

等、不満の多い所です。
PICT8 をインストールすると、画像を開くすべてのストア アプリで、PICT8 のUIを使って画像を選択することが出来るようになります。

・ファイル名表示
・撮影日・カメラメーカー・画像の縦横サイズ・ファイルサイズ等のプロパティ表示
・画像に位置情報が含まれる場合、住所に変換して表示
・画像のプレビュー・拡大表示

等、OS標準のファイルピッカーには無い多くの機能を全てのストアアプリで使うことができます。

PICT8 の弱点

いわゆる画像ビュアー、コミックビュアーとは少し違うところがあります。

・「画像編集機能」はありません。

画像の回転、エフェクトのような機能は一つも持っていません。
PhotoShop Express のような専用ソフトがありますので、そちらをお使頂いたほうが便利です。
ですが、PhotoShop Express のようなストアアプリから画像を開く際には PICT8 を使う事ができます!

・「本棚」はありません。

コミックビューアー、漫画ビュアー的なアプリの多くは「本棚UI」を採用しています。
アプリからファイル ピッカー経由でフォルダを開き、ファイルを探して「登録」するとアプリ上の「本棚」に表示される、というタイプのものです。
PICT8では、その代わりにアプリ上でフォルダそのものを高速に表示しますので、そこから直接ファイルを開いて頂ければと考えています。
そのかわり、ZipやPDFのファイル本体に対してサムネイルを表示することができません。

・まだ完成していません…

上に挙げた機能は入っているのですが、Integration, 摺合せがまだまだでして…


2014年7月26日土曜日

暑中お見舞い申し上げます

Coke

お暑うございます。体力的に年々夏が辛くなってきています。特に今年は厳しく、こなせる作業量が減っているのを感じています。うう。がんばろう。皆様はお加減如何でしょうか。

今、PICT8 という 画像ビューア兼ブックリーダーを作っています。

  • 素早く軽快なファイルブラウズ
  • Zip・PDF見開きリーダー
  • 他のアプリから画像を開くのにも使えるFile Picker Contract機能

あたりが売りです。んが、お盆までに出来るかどうか…うーn。

OS標準のファイル ピッカーの代わりに、プレビュー・プロパティ表示付きのピッカー機能を
提供しよう!という。結構便利。
EXIFに位置情報が入っていればBingに問い合わせて住所も出します。


では。どうぞご自愛ください。
写真は横須賀美術館から見た浦賀水道です。海に自販機の赤が映えていました。

2014年5月17日土曜日

WiFiSD8 Release 6

ストアアプリ版 FlashAir Client WiFiSD8 Release 6 を公開しました。Windows ストア からダウンロードできます。
既にインストール済みの場合、順次自動的に更新されます。
Note - English description available at the bottom of this post.
Click で ダウンロード

変更点

  • 画像の保存先フォルダが存在しなかった場合、アプリケーションが終了してしまう不具合の修正

Changes

  • Fix - App crash when 'Download Folder' is removed or renamed.

2014年5月13日火曜日

futa8 Release 25

futa8 Release 25 が Windows ストアからインストール出来るようになりました。
既にインストール済みの場合、順次自動的に更新されます。

http://apps.microsoft.com/windows/app/futa8/17a26f04-9d9d-4614-ae0f-f807f4938ee9
クリックでストアに移動

 インストールに成功すると、futa8 のバージョンは 1.1.0.140 になります( チャーム→ 設定→アクセス許可、で確認できます)。
Note - English description available at the bottom of this post.

変更点

  • 画像の保存先フォルダが存在しなかった場合、アプリケーションが終了してしまう不具合の修正

Changes

  • Fix - App crash when 'Download Folder' is removed or renamed.

2014年4月5日土曜日

Universal App に備えたい(なるべくお金をかけずに)

(追記 2014/10/25 ... Nokia RDA が2014年8月に終了した件を追記しました)

build 2014 で発表されたuniversal Windows app。
Windows Phone 8.1でWinRT API が動くようになることから、Windows 8.1、 Windows Phone 8.1、 将来的にはXbox ONE でも同じストアアプリを展開することが可能になります。



ただ勿論、同じXAMLのUI 部品にしてもWin8とWPでは中身が違う部分が多いので、UIレイヤについては別コードとなる部分が多いです。別バイナリを1パッケージにまとめて出す感じ。

細かい文句はありつつ全体としては超Welcomeなので、是非やってみたい。のですが、一つ障壁がありまして、

開発に必要なWindows Phone 8.1 エミュレータを動かすには、割と最近のCPUが必要

仮想化を使っているため、Corei3,5,7あたり以降のCPUが必要です。
我が家のCore2Duoは基本×、ダメ、動作しません。酷い。

じゃあ開発マシンをリプレースすればいいじゃない、とマリーアントワネットみたいな事を言える環境には居ないので、どうしようか、というのが以下の話です。

1. WP8の実機を買う


これが実は結構安いです。Amazon.comだとLumia520 が$59で売ってます。開発マシンリプレースより安い。
ただし、この$59のLumia, GSM Onlyなので日本で安いSIM挿して使う、事は出来ないです。完全に開発検証専用ですね。

安!!
これについてはストアアプリ 2ch Sankaを作っているIkuさんに教えて頂きました。有難う。
日本でも使える…W-CDMAなんかが使えるモノについてはExpansysあたりで売ってますが、そこそこのお値段なので今回は除外。
それと、今売っているのは「まだ」Windows Phone 8です。Windows Phone 8.1へのUpdateはもう少し先になります。


2. Nokia RDA - Remote Device Access を使う


※Nokia RDA は2014年8月に終了しました。
端末のカメラを起動するとラボ内の様子が写ったりして、面白いサービスだったのですが。
以降はサービスが運用されていた頃の話です。

――――――――

Nokiaが開発者向けに行っているサービスです。
Nokia社内のラボに設置してある多数のNokia端末に、JavaのRemote Access Appを介して接続できる、という物です。無料。

Nokia RDA
http://developer.nokia.com/resources/remote-device-access

Nokia RDA で端末にリモート接続している様子

左のブラウザに沢山表示されているのが、ラボ内で接続Readyになっている端末。Lumia以外にもAndroidのNokia X等が数十台あります。
JavaのClientで接続し、端末に自分のアプリをインストールして動作を確認する、という感じです。

VS2012 for WP8でビルドしたアプリを、
リモートのLumiaにインストール・実行している様子

ただ、リモート故、パフォーマンスはそれほど良いものではありません。
これ「だけ」で開発を行うのは正直かなり厳しいと思います。
上に挙げた安Lumiaでごりごり開発しつつ、こちらで様々な端末での動作を確認する、という使い方になるでしょうか。

また、こちらもまだWP8.1機は入っていないようです。