【HTML5とか勉強会】Tizen基礎知識と今後の期待
WIndows 8から多少ズレますが、「HTML5とか勉強会」に行ってきました。
■HTML5とか勉強会
目的は「Tizen」の情報収集。
ご存じの通り、Tizenは次期モバイル端末OSで、端末も含めて開発が出来ます。
基本的にはAndroid同様の端末系機能+HTML5での開発が出来るので、タブレットでも作られた日にはWIndows 8の普及に無縁とも言い難いという事で、内容をざっくり共有したいと思います。 (コミュニティとしてTizenJapanコンソーシアムの方々がどんな情報持っているかも気になったので)
■概要
まず、今年になって流れているメディア報道では誤解を招く部分が多々あるとの事。
TIzenの生い立ちが一般的には「"MeeGO"と"LiMo"が流れてHTML5というキーワードでTizenになった」というイメージが、本当はもっと複雑。
Tizenといっても車載向けのTizen IVIと携帯向けのTizen Mobileの2つがあり、中身は全然違うので注意。(最終的には統合されるかも?)
モバイルTizenの仕様を作っているのはTizenアソシエーション(http://www.tizenassociation.org/ja-JP/)で、その仕様に則って各メーカやキャリアが開発している。Tizen=Sumsungやインテルというイメージがあるがそうではない。
そもそもSumsungとintelでもロードマップが違う(インテルは2.0を発表せず、Sumsungは今年夏に予定している)
◯TizenWebAPI概要
■Tizenアプリの種別
2.NativeApp(C/C++)
3.HybridApp(HTML5,JS,CSS and C/C++)
■開発環境(SDK)について
・Tizenを開発するにはSDK(eclipseベース)が必要。今は2.0αが最新だが、2.0αでもまだWebAPIでの開発しか出来ない。動作環境もMacではNG(Windows32/64bitまたはUbuntu32/64bit)。
■SDKで出来る事
・HTML5のコーディング
・wgtパッケージの作成
・Tizenでバイスへのwgtパッケージの送信
・デバッグ
・デバイスエミュレーターとWebシミュレーター
□SDKダウンロードサイト
https://developer.tizen.org/downloads/SDKs
■エミュレータとWebシミュレータ
現状、作ったアプリを動かす為には以下3種類しかない。
・Tizen DevPhone
・TizenDevice Emulator
・TizenWeb Simlator
Tizen Device EmulatorのターゲットはARM(つまりHTML5関係ない)。
Dviceが完全にエミュレートされているのは素敵だが、その動きは限りなく遅い。
Chrome上で動作する「Tizen Web Simlator」の方が動作が速いので、今アプリ開発をするなら最終確認だけデバイスエミュレータを使うくらいで良い。
■TizenWeb Simlator
・アプリにMassagingを投げる
・Call➡通話のAPIが用意されているので
・Geolocation
・Timezone
・Device & NetworkSetting(3G,WiFi,LTE)
・Battery
・NFC Adapter
・PawworManager
・Webアプリ動作時のHTML5スコア
(゚ー゚)y-.。o○(別に良くもわるくもないかんじ)
■TizenWebAppsについて
・WebAppsの仕様はW3Cの仕様に準拠している。".wgt"
・XMLのコンフィグレーションはAndroidのManifestとほぼ同じような気がする。
APIの種類は4種類
・Tizen Device API
・Tizen Web UI Framework(基本的にはJqueryMobile)
■FIreFoxOSとの違い
Tizenの場合はHTML5だけじゃなくNativeでの開発が出来るくらい。
■コミュニティ活動について
・Tizen勉強会を毎月豆蔵さんオフィスで開催中との事
・詳しくはTizen Japanコンソーシアム(GoogleGroup)へ
https://groups.google.com/forum/#!forum/tizen-japan
★結論(個人見解)★
オープンとはいえTizenその物の仕様や開発環境も成熟しておらず、開発が各社独自なので急激な成長は無いと思われる。また、Tizen IVIもTizenMobileも他OSと差別化する要素が現状無い為、昨年末のdocomoが日本市場に投入するという話も懐疑的。
HTML5の公式サポートはWindowsストアアプリやWIndowsPhone8でもやっている事なので目新しさはなく、Nativeでの実装方法(C/C++)が見えない限り、Androidとの違いも何とも言えない。。Nativeでメーカがバリバリにチューニングしたアプリならば速そうだけど。
HTML5やjQuey、JS等のWeb技術は用途が拡がっているので言語レベルでの技術的にはやはり先行するのが大事だとは思いますが、OSとしてはTizenよりはWindows Phone8を待つほうが現実的かと。
なんとも。
1/18(fri) Windows 8 Developers 第1回イベント(Tokyo)を開催します!!
掲題の通り、WIndows8 Developer主催のカンファレンスイベントをマイクロソフトさん品川本社でやらせて頂きます!!
前回行ったハッカソンは完全に「作る」という事で技術主体だったのですが、今回はカンファレンスなのでセッションを通じた情報の発信と参加される方々の交流がメイン目的となります。
色々と考えたのですが、やはりビジネスとしてWindows8を取り込みたい方の為には平日の夜というビジネスタイムが最適だと考えての平日夜開催です。
初回で手探りな部分もあるので時間も短めですが、内容は幅広くやるつもりです。
セッション内容は下記の通り。
Session Program
Windows ストアアプリ 開発概要
日本マイクロソフト株式会社
デベロッパー & プラットフォーム統括本部
第一クライアントプラッフォーム推進部
テクニカルエバンジェリスト 渡辺 友太
既存JSフレームワークを利用したWindowsストアアプリ開発
株式会社ジャムロジック
Ext Japan シニアアーキテクト 野村 亮之
スマートデバイスとしてのWindows 8アプリ開発の可能性
株式会社ソニックス
スマートデバイスソリューション事業部
コンサルティンググループ 川崎 順平
渡辺さんはエバンジェリストとしてメディアだけでは見れないような旬な情報を提供してくれます。野村さんは8nightsでも講演されてましたが、今回は倍の時間を使って8nightsよりも「濃い」お話をしてくれます。
カンファレンス名はAmplifierとしました。
参加する人同士のコミュニケーションと発信する情報の相乗効果で参加される方々のビジネスを増幅させるような、そんなイベントにしたいと考えての事です。
最後に、当コミュニティのボードメンバーも今回のカンファレンスで募りたいと考えております。
特殊技術や何かに精通していなくてコミュニティ運営にご興味ある方は是非一緒に活性化をさせて行きましょう。
定員は70名となっておりますが、是非お早めに下記ATNDからお申し込み下さい★
Windows8の開発情報を発信するコミュニティの第1回カンファレンスイベント[場所]マイクロソフト品川本社http://www.microsoft.com/ja-jp/mscorp/branch/sgt.aspx
【C#】タスクの実行とキャンセル、バックグラウンドからのUI更新
並列処理というか非同期処理って重要ですよね。
そこで今回はUI更新を伴うトグルボタン的なものを書いてみました。
■概要
①ボタンを押すと、ボタンテキストの更新を開始します
②ボタンテキストにはTask内のループカウンタを表示します
③テキスト更新中(Task実行中)にボタンを押すと、ボタンテキストの更新(Task)を停止します
■ポイント
①CancellationTokenSource (Taskのキャンセルに利用)
②SynchronizationContext (Task実行中にUIを更新するために利用)
privateint counter_ =0;
privateTask task_ =null;
privateCancellationTokenSource tokenSource_ =null;
// タスク終了時に実行する処理
private async TaskEndTask(int n)
{
Debug.WriteLine("EndTask: counter = {0}", n);
}
// タスクの実行・停止を行うボタンのハンドラ
private async void StartButton_Click_1(object sender,RoutedEventArgs e)
{
if(task_ !=null)
{
tokenSource_.Cancel();
task_ =null;
await EndTask(counter_);
}
else
{
var context =SynchronizationContext.Current;// バックグラウンドからUIの更新要求を行うためのContext取得
tokenSource_ =newCancellationTokenSource();// 外部からTaskへキャンセル要求を発行するために必要
// タスクの開始
task_ =Task.Factory.StartNew(
async (_)=>
{
counter_ =0;
while(true)
{
// キャンセル要求の確認
if(tokenSource_.IsCancellationRequested)
{
context.Post(state =>
{
StartButton.Text="キャンセルされたよ!";
},
null);
}
// Taskのキャンセル要求を検出したとき、例外を生成してTaskを終了する
tokenSource_.Token.ThrowIfCancellationRequested();
// SynchronizationContextを利用したUI更新
context.Post(state =>
{
StartButton.Text= counter_.ToString();
},
null);
counter_++;
// 表示テキストの変更を目視できるようにループ間隔を制御
await Task.Delay(TimeSpan.FromMilliseconds(30));
}
}
, tokenSource_.Token// このタスクをキャンセルするCancellationToken
);
}
}
Windows 8ストアアプリでペイントツールを作ってみた[JS]
タッチして指で書けるペイントツールを作ってみようと思いました。
ただ、C#だと色々と面倒くさそうな予感がしたのでtmlib.jsあたりを使ってサクッと出来るかなーと思ったらなんか色々とエラーが出たので断念。※エラーの詳細を見るほどのモチベーションは無かった
そこでふと思ったのが世の中にはHTML5というものがあってHTML5にはcanvasがあるじゃないかと気付き、方向転換。
結果的に割と簡単にできたのでここで紹介します。
必要なファイルはたったの3ファイルです。
まず最初に土台となるHTMLをご説明します。
[default.html]
<!DOCTYPE html>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/>
<metacharset="utf-8"/>
<title>WhiteBoard</title>
<!-- WinJS 参照 -->
<linkhref="//Microsoft.WinJS.1.0/css/ui-dark.css"rel="stylesheet"/>
<scriptsrc="//Microsoft.WinJS.1.0/js/base.js"></script>
<scriptsrc="//Microsoft.WinJS.1.0/js/ui.js"></script>
<canvasid="mycanvas"width="1400"height="800"></canvas>
<!-- simplepaint 参照 -->
<linkhref="/css/default.css"rel="stylesheet"/>
<scriptsrc="/js/default.js"></script>
</head>
<body>
</body>
</html>
ご覧の通り、自分の書いた部分はcanvasの定義しただけです。
次に飾りつけのCSS
[default.css]
body {background-color:#fff
}
@media screen and(-ms-view-state: fullscreen-landscape){
}
@media screen and(-ms-view-state: filled){
}
@media screen and(-ms-view-state: snapped){
}
@media screen and(-ms-view-state: fullscreen-portrait){
ホワイトボードっぽくしたかっただけなのでbackgroundを白くしただけです。
見た目の部分はこれだけで完了。
いざ、実行。
こんな感じで愚直に真っ白なキャンバスが画面いっぱいに表示されます。
さー、ここに実際にタッチで描画する処理をJSで書いてあげましょう。
[default.js]※app.start();のあと
var drawFlag =false;
var oldX =0;
var oldY =0;
window.addEventListener("load",function(){
can = document.getElementById("mycanvas");
can.addEventListener("mousemove", draw,true);
can.addEventListener("mousedown",function(e){
drawFlag =true;
oldX = e.clientX;
oldY = e.clientY;
},false);
can.addEventListener("mouseup",function(){
drawFlag =false;
},false);
context = can.getContext("2d");
context.strokeStyle ="rgba(0,0,0,1)";
context.lineWidth =5;
},true);
//描画するところ
function draw(e){
if(!drawFlag)return;
var x = e.clientX;
var y = e.clientY;
// var can = document.getElementById("mycanvas");
//context.beginPath();
context.moveTo(oldX, oldY);
context.lineTo(x, y);
context.stroke();
//context.closePath();
oldX = x;
oldY = y;
}
})();
この辺はHTML5 のサンプルから土台を持ってきたのですが、
そのサンプルがstaticの使い方がおかしかったりしてレンダリングが飛んだりしたのでその辺はちょっとカスタマイズしました。
ここで気付いたのがイベント処理自体はWeb同様にmousemoveとか書いて大丈夫だってところです。
まあ、タッチパネル搭載してないWin8もゴロゴロいるので当たり前といえば当たり前なのですが。
で、実行してみました。
書けた。
この手書き感溢れるクオリティがたまらないですね。
AndroidとかiPadで手書きアプリって本当に使ってる人いるのだろうか。
ちょっとレンダリングの都合上、カスれてるところもあるのですが、そこはチューニング次第で何とでもなるかと思います。
(個人的には書く事が目的だったのでやりません)
ちなみに書いたものは消せないし、色も太さも変えられないので、このままツールにするには厳しいかもしれませんが、
タブレットとかでは需要のある機能かもしれないので自由にカスタマイズの参考としてください。
明日はC#でマニアックにAcynkTask的なものをご紹介します。
(いったい何人が得するのか分かりませんが)
では。
【C#】設定コントラクトの利用
ちょっとコードが長くてわかりにくいですが、設定チャームを利用して、アプリケーションの設定を行う方法を記載します。(コードを記載する場所は、MainPageがわかりやすいと思います)
ここでは、SettingPage.xaml を設定メニューに追加することを前提に記載します。(呼び出し元はMainPage)
MainPage.xaml.csのコード
// 設定チャームへの追加を行う
void onCommandsRequested(SettingsPane settingsPane,SettingsPaneCommandsRequestedEventArgs eventArgs)
{
// ハンドラの取得
UICommandInvokedHandler settingPageHandler =newUICommandInvokedHandler(onSettingsCommand);
// settingPageというIDで設定というメニュー(SettingCommand)を追加します
SettingsCommand settingPage =newSettingsCommand("settingPage","設定", settingPageHandler);
eventArgs.Request.ApplicationCommands.Add(settingPage);
}
// ポップアップウィンドウの定義
privatePopup popup;
// ハンドラから呼び出された時の処理内容
void onSettingsCommand(IUICommand command)
{
SettingsCommand settingsCommand =(SettingsCommand)command;
constdouble _settingsWidth =400;// 「SettingPage.xaml」画面の幅の設定
constdouble _settingsHeight =768;// 「SettingPage.xaml」画面の高さの設定
popup =newPopup();// ポップアップのインスタンス化(空白のポップアップを作る)
popup.Closed+=OnPopupClosed;// ポップアップがクローズされた時に呼ばれるメソッドを定義
Window.Current.Activated+=OnWindowActivated; // ウィンドウがアクティブになった時に実行されるメソッドを定義
popup.IsLightDismissEnabled=true;// 簡易非表示の設定を有効化(アプリが別操作をした際に非表示になる)
popup.Width= _settingsWidth;// ポップアップウィンドウの幅の設定
popup.Height= _settingsHeight;// ポップアップウィンドウの高さの設定
SettingPage settingPage =newSettingPage();// 「設定」のページのインスタンス化
settingPage .Width= _settingsWidth;// 「設定」のページの幅を設定
settingPage .Height= _windowBounds.Height;// 「設定」のページ高さを設定
settingPage .setCallPage(this); // 後ほど説明
// ポップアップの中に「設定」のページを設定(こうすることで、呼び出し元画面が表示されたままで設定画面が表示される)
popup.Child= settingPage;
// 左からの位置指定(設定画面の幅が400、画面全体解像度が1366なので 966の位置が丁度よくなる)
// 画面サイズによって位置を調整するにはウィンドウのサイズを取得してから減算したほうがよいです
popup.SetValue(Canvas.LeftProperty,966);
popup.SetValue(Canvas.TopProperty,0);// 上からの位置指定
popup.IsOpen=true;// ポップアップをオープンする
}
// アクティブ時の処理内容
privatevoidOnWindowActivated(object sender,Windows.UI.Core.WindowActivatedEventArgs e)
{
// アクティブ時の処理を記述します。(今回は特に何も処理しません)
}
// ポップアップを閉じた時の処理内容
voidOnPopupClosed(object sender,object e)
{
// アクティブ時に実行されるメソッドを削除
Window.Current.Activated-=OnWindowActivated;
}
SettingPage.xaml.cs のコード
// 設定画面のバックボタンを押下した時の処理
privatevoid onBackClicked(object sender,RoutedEventArgs e)
{
// 設定画面の親(Popup)を閉じる
Popup parent =this.ParentasPopup;
if(parent !=null)
{
parent.IsOpen=false;
}
}
設定画面(SettingPage)で設定を変更して、呼び出し元(MainPage)へ反映させるには、MainPageをSettingPageに渡して
SettingPageからMainPageのメソッドを呼び出すような仕組みがよいのではないかと思います。
例
SettingPageのコード
// MainPageを受け取る
MainPage _mainPage;
publicvoid setCallPage(MainPage page)
{
_mainPage = page;
}
// 設定画面で何か設定変更をした場合の処理
privatevoid onClickHoge(object sender,RoutedEventArgs e)
{
// MainPageの処理
_mainPage.hogehoge(data);
}
MainPageのコード(SettingPageから呼び出されるメソッド)
publicvoid hogehoge(string data)
{
textData.Text= data;
}
C#でのタイマー実装
C#におけるtimerの実装についてです。
今回はハッカソンvol.1にて田中さんが作ったパズルゲームに使われているタイマー処理をそのまま共有します!!
まずタイマーのイメージですが、こんな感じです。
「経過時間」と表示されている部分ですね。
これが実際に毎秒カウントされる形になります。気になるコードは下記の通り。
■タイマーの実装
タイマーとして DispatcherTimer を使用すると時間の表示などを行うのに便利です。
privateDispatcherTimer timer;
privateDateTime startTime;
privatevoid startProcess()
{
startTime =DateTime.Now;
}
// タイマーを設定するためのメソッド(初期処理などで呼びます)
privatevoid setTimer()
{
timer =newDispatcherTimer();
// 下のTickで指定した処理を行う間隔を指定します。(下の例は1秒間隔)
timer.Interval=newTimeSpan(0,0,1);
// onTimerメソッドをIntervalで指定した間隔(上の例では1秒間隔)で行う処理として設定します。
timer.Tick+= onTimer;
}
// Intervalで指定した間隔で呼ばれる処理
privatevoid onTimer(object sender,object e)
{
// 現在時間取得
DateTime now =DateTime.Now;
// 開始時間と現在時間の差分を取得
TimeSpan timeSpan = now.Subtract(startTime);
// TextBlockなどに差分の時間を表示
string timeText =string.Format("{0:00}:{1:00}:{2:00}", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);
time.Text= timeText;
}
// タイマーの開始(ボタンのイベントなどで呼びます)
private vid onStart()
{
// DispatcherTimerを開始します。(止めるときは、Stop()メソッドを使います。)
timer.Start();
}
privatevoid onStop()
{
timer.Stop();
}
※コードはwin8devメンバーの田中さん提供
今回は画面表示を元にしていますが、別スレッドでの時間カウントが必要な場合にも表示部分を抜いて変数で判断すればそのまま使えます。
メトロのアプリはデスクトップと表示が切り離されるのでこういった時限処理は今後有効に使えそうですね。
では。
JavaScriptプログラムにおけるJSON取得とコールバック
Windows8開発でJavaScriptを始められる方、Webページ制作からプログラミングに移行される方も多いと思うので今回はデータ通信の基本、JSONについてご説明します。
「XMLならやってるけど、JSONはやった事ない」という人は必見です。そもそもJSONってなあに?という人はまずは下記サイトをご覧下さい。
[参考]※ThinkIT
http://thinkit.co.jp/article/70/1
元々、JavaScriptとの親和性も高く、JSONを利用することで冗長なXMLと比べて通信時のデータ量を削減できるなどのメリットもあります。サーバサイドも一括で開発する際には更に通信速度を向上させるライブラリも多数出ているので通信データ量が増大している昨今では必須の技術です。
実装時、アプリ側のコードは以下のようになります。
今回のコードは外部APIを利用する事を想定しています。
json取得と4つのコールバック
// test log
console.log("test");
// get element this p tag
var progress_el = document.getElementById("progress");
var response_el = document.getElementById("response");
// http request準備
var xhr =newXMLHttpRequest();
xhr.open("GET","{ API URL }");
xhr.responseType ="json";// others arraybuffer, blob, document(html or xml), text, ms-stream
xhr.timeout =10000;
// 4つのコールバック
// 取得した
xhr.onload =function(){
if(this.status ===200){
// receive
var response =this.response;
console.log(""+ response);
response_el.textContent = response.toString();
progress_el.textContent ="complate!";
}else{
// faild
}
};
// 取得中
xhr.onprogress =function(e){
if(e.lengthComputable ===true){
progress_el.textContent = parseInt(e.loaded *100/ e.total,10)+"%";
}else{
progress_el.textContent ="loading...";
}
};
// タイムアウト
xhr.ontimeout =function(){
progress.textContent ="timeout";
};
// エラー
xhr.onerror =function(e){
progress.textContent ="error!";
};
// request send
xhr.send();