Quantcast
Channel: kenji matsuokaのニッキ
Viewing all 342 articles
Browse latest View live

Google I/O 2016で発表される事三日目

$
0
0
今年はI/Oが3日間行われます。去年までの2日間と比べ日付だけみると1.5倍ですが、同時セッション数も増えているのでセッション数の比較で言うと、いま発表されているだけでも3倍以上増えています。
全体的な特徴としてはAndroidが多いのは去年と同じながら、Progressive WebとFirebaseのセッションが増えていること。
逆にFirebase以外のDriveやGAEのようなGoogle系クラウドサービスのセッションはあまり多くないようです。
このあたりは今後コードラボなどに組み込まれていくのかもしれません。

より詳細な内容の翻訳はしばらくお待ち下さい。
Google I/O 2016で発表される事 初日
Google I/O 2016で発表される事 二日目
>Google I/O 2016で発表される事 三日目

9:00 日本時間1:00

Android アプリケーション・アーキテクチャ 次の10億に備える


Google Maps APIによる流れるような開発者経験


10:00

モバイルウェブにおける継ぎ目のないチェックアウトの実現


Firebaseデータベースのゼロヨン


Mobile Vision API:アプリケーションのデバイス上のビジョンを提供する。


アプリ開発者に向けたGoogleのモバイル開発者向けツールの秘訣


11:00 日本時間3:00

進化したData Binding


Web Push notificationでユーザーと深く繋がる


投票2016:ビッグデータで大統領選に決着をつける


アプリのアクセシビリティについて包括的な設計とテスト


リサイクルビューの内外


Firebaseでゼロからアプリを作る


13:00 日本時間5:00

井戸端会議:現実世界におけるGoogle


AMPがどうやってスピードを出しているか


クロスプラットフォームのレスポンシブデザイン


2016年のWeb開発ワークフロー


ARTの進化


14:00

Kubernetesを使用してクラウドを管理する最適な方法


数分であなたのアプリをAndroid TVに適合させる


Houdini:CSSの未来を謎解く


Instant Loading:オフラインで高速なProgressive Web Appsを構築する


FirebaseにおけるProgressive Web


タイミングが全て、入り組んだアニメーションのトリック


素晴らしいアプリを作るためにAnalyticsを使う


15:00

Android ハイパフォーマンスオーディオ


Androidイン・モーション


PolymerとProgressive Web Apps:モダンWebを作る


V8モダンなJavaScriptとその先


16:00

バーチャルリアリティゲームをライブコーディング


Eマウントフルサイズ50mm SEL50F18Fショートレビュー

$
0
0
SONYから新しいEマウントレンズSE50LF18Fが発売されました。
SEL50F18Fは登場前から色んな意味で注目していました。

一番はなんといってもEマウントのフルサイズとしてSONY初の50mm単焦点レンズとなること。
50mm単焦点といえば、レンズ業界では標準レンズ等と言われ、ド定番のレンズなのですが、なぜか今までEマウントのフルサイズにはSONY純正でこのラインナップがありませんでした。

もう一つの問題として、Eマウントフルサイズはレンズがハイエンドに偏っていて殆どのレンズがGレンズあるいはツァイスブランドになっていて、レンズを買うなら10万円近い出費は覚悟しないといけない状態。
そんな中SEL50F18Fは実売で3万円前後というかなりお買い得感の高いレンズとなっています。

ハイエンドに振りすぎている関係から重たいレンズも多く、α7のコンパクトな筐体には似合わないと思っていたのですが、SEL50F18Fは小型軽量で気軽に持ち運べそうなのも注目したポイント。

それでいてf/1.8とかなり明るいレンズなのも見どころ。
もっとも、フルサイズということもありそこまで極端に絞り開放にする必要はないのでしょうが、それでもフルサイズらしいぼかしを手軽に楽しめるのはうれしい。

ということで、発売日に即買しました。
第一印象はとにかく軽い、小さいということ。


SONYの50mm単焦点といえば、神レンズともいわれたAPS-C専用のSEL50F18(最後にFがつかない)がありますが、コレと比べてもぱっと持った瞬間に軽いことがわかります。

実際に測ってみるとSEL50F18Fはレンズキャップ込みでわずか187g。SEL50F18は同じ条件で222gなので2割近くかるいです。
α7にキットレンズとしてついてくるSEL2870は331gでした。実測値以上に重心がカメラ本体に移ったことで、手に収まってる感覚が強く持ちやすいと感じます。

左がSEL50F18、右がSEL50F18F


大きさで言うと外径はSEL50F18Fが大きいですが全長は短く体感的には同等のサイズと言う感じ。
左がSEL50F18、右がSEL50F18F


SEL50F18は金属ボディ、SEL50F18Fはプラスチックだとか、SEL50F18Fには手ぶれ補正がないとかいう違いがあるとはいえAPS-Cのレンズと同じ焦点距離、同じ明るさでこれは驚き。

それではSEL50F18Fで実際に撮影してみます。撮影したカメラはα7sです。

キットレンズのSEL2870と比較してみます。このレンズはズームレンズなので使い勝手は良いです。
明るさではf/3.5〜f/5.6なので足元にも及びませんがフルサイズならそこまで開放で撮ることも少ないのでまずは同じ明るさで比較してみます。
単焦点は画質がいいといいますが、実際のところどの程度差がでるのかについても見てみましょう。
画像は800px(HiDPI環境では1600px)に縮小しています。

SEL2870 50mm(と思ったけれど後で調べたら51mmになっていました)
50mmに合わせて最も絞りを開くとf/4.5となりました。流石にフルサイズだけあってf/4.5でもそれなりにぼやけています。


同条件でSEL50F18Fで撮影するとやはり綺麗。
劇的に違うというわけではないですが、ピントが合っている場所はよりくっきりとしているし、周辺が暗くなる現象も抑えられて全体が均一の明るさになっています。

等倍で切り出すとこんな感じ

SEL2870ではピントが合っているところでも見比べると僅かにぼやけているのがわかります。


こちらはSEL50F18F特に目玉の周りや首周りを見るとよりくっきり写っています。


とはいえ、f/4.5しか出せないところでf/4.5で撮影するのとf/1.8出せるところをf/4.5で撮影するのでは性能差が出て当然。
ということで、SEL2870で最も画質が良くなると言われるより絞ったf/7.1で比較してみます。

こちらがSEL2870
悪くない画質です。


こちらがSEL50F18F
やはり、絞ってみても単焦点のほうが綺麗なようです。全体的にくっきり写っていますし、特に画面端あたりのラインが綺麗。
SEL2870は画面端に行くとボケのようなブレのような曖昧さが出てきますがSEL50F18Fはそれが目立ちません。


絞り開放をためす。
最後に絞りをf/1.8にしてみます。
さすがにフルサイズでf/1.8はよくボケますね。ボケ方もすごく綺麗という感じではないですが価格を考えれば十分な感じ。
ボケるまでの繋がりも自然でピントが柔らかくあたっている感じがします。


ピントを一番近寄せるとこんな感じ。
よくボケてくれています。


ここがダメ。
べた褒めましたが、正直なところ、このレンズの役割は軽量な筐体でそれなりの画質を安価に届けるということに特化しています。言い換えるとそれ以外のところは本当に雑。
高級感なんてのはかけらもなくローエンドのデジカメみたいな質感ですしなんといってもオートフォーカスがすごく遅くてうるさい。
なんだか20年前くらいのAF一眼と呼ばれていた時代を思い出しました。
ギーギーカチャッギギーカチャッとモーター音が激しいし困ったことにミラーレスってファインダーの機能を提供するため定期的にオートフォーカスを動かすので電源ONの間ずっとギーギー鳴りっぱなしMFで使いたいと思ったほどです。
さらにフォーカスを動かすとレンズが飛び出します。 これは驚きました。今時ローエンドでもこんなレンズ見たこと無い。


SEL50F18Fって価格的にSEL50F18に近くて、サイズもあまり変わらず重さはむしろ軽い。それでいてフルサイズに対応するということでSEL50F18はもう消滅するのではないか? なんて噂を聞きましたがレンズの格が1段階違う印象です。
なんだか新商品を買ったというよりは古い中古レンズを掘り出したような気持ちになってしまいました。

おすすめ度
80%(多くの人におすすめ)
AFが信じられないほど酷いし高級感のかけらもないですが、この値段を実現するためと思えば仕方ないかなと、しばらくはMFを中心に使ってみようと思っています。
明るく、軽く、安い50mmということでEマウントフルサイズでは他に選択しがない状態なのでα7シリーズユーザーなら持っておいて損がないレンズのように感じます。
望むならAF改良版が+2万円くらいで出てきたら動画を撮る人や動きの激しい物を撮る人にも優しくなったような。


以下作例



トリミングで中望遠的な使い方をしてみた例

地元でI/Oが楽しめるGoogle I/O Extendedが今年も開催

$
0
0
Google I/Oの周辺イベントであるGoogle I/O Extendedが今年も全世界で開催されます。
もちろん福岡でも開催しますが、今年は例年といろいろな変更点が有ります。
一番の変更点は、I/Oをパブリックビューイングする昨年までのI/O Extended ライブストリーミングに加えて後日に現地に参加した技術者が直接話すI/O Extended報告会が開催されます。
昨年までは同様のイベントをDevFest I/O報告会という名前で行っていましたが今年はI/O Extended報告会と名前を変え大幅にパワーアップします。


Google I/O Extended ライブストリーミング 2016

イベント概要

最初のI/O Extendedは昨年までのI/O Extendedと同様に現地の基調講演をYouTube Liveでパブリックビューイングします。
注:大変申し訳無いのですが今年は同時通訳を確保することが出来ませんでした。代わりにハッシュタグ #io16jp にて有志の翻訳を行う予定です。

日程

開演時間は日本時間で19日 午前2:00〜4:00まで開催予定の基調講演を含む時間帯で全国同時開催です。
詳細な開始終了時刻は会場により異なります。
福岡開場の開催日時は5月18日(水) 23:30〜19日(木)早朝
平日深夜ということでなかなか参加しづらいかもしれませんが、珍しい形態のイベントなのでぜひ参加してもらいたいです。
特に5時から始まるWhat's New Androidについては早起きすれば比較的参加しやすいかと思います。
現地の予定から言うと、19日 深夜2:00に基調講演が開始、5時にWhat's New Androidが開催される予定です。
現地の状況がわからないため確約はできないのですが、可能であればもっと早い時間に現地より会場付近の様子を伝える中継を行いたいと思っています。

開催場所

詳細な開催場所は各申し込みサイトを参照して下さい。
福岡会場はヌーラボ新社屋で開催します。
昨年まで開催していたAIP Cafeから変更になっているためご注意下さい。

参加申し込み

申し込みはオンラインで行えます。
福岡
大分
徳島
神戸
京都
上田
甲府
東京
函館
その他の地域についてはI/O Extended公式サイトをご確認下さい。

Google I/O Extended 報告会 2016

イベント概要

昨年までDevFest I/O報告会と呼ばれていたイベントについて今年はGoogle I/O Extended 報告会と名前を変えて大きくパワーアップします。
Google社員やGoogle Developers ExpertなどI/Oに参加した技術者がI/Oでセッションの紹介や技術の解説を行います。

今年は昨年までの全国同時中継をやめて全国を回るツアー形式とすることで、各会場に多くのスピーカーが直接訪問します。これによりスピーカーと直接交流することが出来ます。
現在会場ごとのスピーカーについては調整中ですがどの会場も豪華なゲストスピーカーを招待する予定です。

開催日時

6/4〜7/9にかけて全国で開催されます。
福岡での開催は6/25(土)です。

開催場所

場所は昨年までの九州産業大学からヌーラボ新社屋へと変更されます。

参加申し込み

申し込みは会場によって異なります。
現在まだ申し込みサイトが出来ていない会場も有りますが、全国8会場で開催予定です。
九州
四国
中国
京都
信州
東京
石巻
函館

Google I/O 2016渡航記 出国編

$
0
0

出発

さて今日からI/Oに行ってきます。

今年は福岡空港を13:00に出る便で成田空港経由の飛行機です。
例年13:00の便を予約して朝1に空港で変更するようにしていたのだけれど今回はUnited航空でANAの便を予約した関係で便の前倒しができませんでした。

成田空港は設備がいろいろあってゆっくり見て回ると結構楽しめるしGoogle I/Oは直前にいろんなゴタゴタが発生することがありますが、そういうときのためにも成田で時間があると調整しやすいのですが、一方で昼便は福岡でゆっくり出来ますね。
昼前に福岡空港に到着してチェックインしたらラウンジで時間を潰し、お昼ごはんを食べて出国しようと思います。

13:00の便に乗った場合、成田空港到着時間は14:50
成田を出るのが17:25なので、定刻通りに行った場合乗り換えは2時間35分
成田空港における国内線から国際線の乗り換え時間は目安が45分程度なので、これでも余裕はあります。

チェックイン

まずは何はなくとも福岡空港でチェックインを済ませます。国際線のチケットだけれど出発は国内線なのでチェックインは国内線ターミナルにある国際線乗り継ぎカウンターで行います。
これを間違えて国際線に行ってしまう人がいるらしいです。国際線に行ってしまうとかなりの時間ロスになって飛行機を乗りそこねてしまうので注意してください。
Unitedで買ってもANA運行の場合はANAの国際線乗り継ぎカウンターに行く。

UnitedでANA運航便を購入した場合、オンラインチェックインができず当日空港でのチェックインが必要です。
チェックイン自体はすぐ終わるし荷物を預け入れるからどうせ窓口に行かないといけないので実害は少ないのですが座席が確定しないのが困ります。

今回は座席がだいぶ開いていたみたいで窓際の席をリクエストしたら福岡-成田も成田-San Franciscoのどちらとも窓際を選ぶことができました。
国際線の場合、できるだけ早いうちに出国ゲートに並べるように前の席を選んでいたのですが、最近は入国審査のスピードがアップしているためそこまでこだわる必要ないみたいです。

手荷物はここで預けてSan Francisco空港まで持って行ってもらえます。
ツアーの場合はチケットが通しではなかったりして
一度成田でピックアップしないといけないことがあるので注意してください。

ラウンジ

無事にチェックインが終わったので
ラウンジでビールを頂きます。
福岡空港はビール一本かソフトドリンク飲み放題かの選択式になっています。
部屋も広いしコンセントも用意されていて使い勝手がいいですね。

出発でビールが飲めると旅の気持ちが盛り上がっていきます。


時間帯によってはパンが置いてあったりするのですが今日はパンはありませんでした。

クレジットカードのラウンジは全体的に空港の不便なところに置かれがちで、福岡空港でも第三ターミナルの端っこ。
出発ゲートは第二ターミナルの端っこで要するに出発ゲートの一番遠いところに置かれています。
歩いて行くにも結構な時間がかかるので出発時間には気を使わなくてはいけません。

いつか便利な航空会社のラウンジが使えるような身分に慣れれば良いのですが、私にはまだ遠い先のようです。
ビジネスクラス以上に乗らないといけないとか、年間の航空機使用回数がすごく多いとか、年間5万円以上のカードに契約しないといけないとかいろいろ敷居が高い。
クレジットカードのラウンジは6000円程度の年会費でラウンジや保証もつくので助かります。(しかも私の場合は家族会員なのでもっと安い)

うどんを頂く

空港の食事は概ね高くてまずいというのが相場だけれど、ここのうどんはリーズナブルで美味しい。
例えばごぼう天うどんなら450円。麺の味が物足りないけれど、スープは昆布だしが効いて美味。


福岡出発

うどんを食べたら出発時間が近づいたので手荷物検査を受けて搭乗口に向かいます。
ゲートは第10番ゲート。今回はギリギリ第二ターミナルだったけれど、福岡-成田便は検査場から遠いことがあるので注意が必要ですね。

ゲートをくぐったら飛行機は到着遅れで若干遅延していました。
成田での乗り継ぎ時間が短いとこういう時に焦らないといけないのが困りますね。

この手の遅延は一度発生するとズルズルと時間が伸びていくので要注意。
と思ったら8分遅れでの出発。思ったより送れなくて良さそうです。
それにしてもすごい雨ですね。


当たり前の話ではありますが、離陸してしまうと晴天の下です。この青空を見ていると下が大雨なんて信じられない。


飛行機に乗ると毎回落語を聞くようにしているのですが、最近のANAは落語が2話しか入っていないので福岡-成田でさえ数週ループしてしまいます。昔は3話入っていたのになぁ

100両以上する高額な器を拾ってきた犬の餌皿にしているお店の話と真田幸昌の2本立て。

フライト中雲だらけでしたが、途中富士山が見えました。


深い緑や水田のきらめきを見ると やっぱりアジアだなぁと感じます。


成田着

当初より30分遅れて成田空港に到着しました。
福岡空港から成田便はいつも沖止めです。遅れをカバーするために空港ゲートに直付してくれないかと期待したけれど、やっぱりバスでした。
結局到着ゲートについたのは15:35、当初から45分遅れで乗り換えの時間は1時間50分です。
エスカレーターを登って


成田空港の場合、空港での乗り換えは二通り、
一回国内線を降りて再度手荷物検査場を通る方法と
国際線乗り継ぎ口を使う方法。
ここで右に曲がって国際線乗り継ぎ口に行くと一気に出国できますが、成田空港の手荷物検査場外にあるショップで買物をしたり、クレジットカード会社のラウンジを使いたい場合は到着口に向かいます。
到着口に行くとそこそこ歩かされて時間が必要なので注意してください。
成田にあるクレジットカード会社のラウンジはビールかウィスキー(水割りかハイボール)が1杯に加えてソフトドリンクが飲めたり、柿ピーが置いてあったりと充実してます。

ツアーの場合、国際線チケットを成田空港で受け取るために国際線乗り継ぎ口が使えない場合があります。ご注意下さい。


成田空港はショップが豊富なので時間に余裕があるなら一度外に出て買い物するのも楽しいかも。
国際線乗り継ぎ口にある手荷物検査を行うとすぐに出国審査があり、空いていれば十数分で乗り換えが可能です。

今回はあまり時間もないので国際線乗り継ぎ口を使って出国審査を受けます。
出国審査の金属探知機は国内線のそれより精度高く調整されているような印象を受けます。以前には靴底の金属に反応したこともあります。

出国審査を抜けると免税店が並びます。
といっても成田空港の免税店は贅沢品が主で生活必需品などは少ないです。
消費税がかからない代わりにもとのお金が凄く高い。
免税店ですが、概ね価格は家電量販店の1.5倍という感じなので価格面でのメリットはありません。
SDカードや充電器など必要な電化製品が揃わない時にはAKIHABARAという店で仕方なく買ったりしますが普段は眺めるだけ。


ちかくにいつも、ウィスキーの試飲をやっている店があるのでそこでいつも一口だけもらっていますが、ここでも買ったことはありません。

搭乗口へは出発の30分前を目安に向かいます。国内線より随分と早いので注意が必要です。
成田空港は空港も広くてわかりにくいので乗り遅れないように事前に場所を把握しておいたほうが良さそう。

San Francisco行きはなぜか同じ17:10発でUnited運航便とANA運航便が同時に出発します。
お互いコードシェアしているので、Unitedで買ってもANAだったり、ANAで買ってもUnitedだったりするのでフライト番号をしっかり確認してください。
なぜこんな不便で紛らわしい運用にしているのか不思議です。


San Franciscoへ

機内にはUSBが装備されていてスマートフォンの充電が可能。電圧は低めで充電には結構時間がかかりました。
ANKERのモバイルバッテリーなら1時間半くらいで充電できるNexus5が6時間かかりました。


国際線の楽しみといえば映画。今や国内線ではモニターがない飛行機が主流ですが、国際線では新作の映画を楽しむことができます。
THE RUNNERという石油流出の対策を行った政治家の映画を見たけれど、うーん という感じ。
ニコラス・ケイジの作品らしいなぁという感想。やたら渋いです。

ANAの魅力は食事が美味しいこと。
最初のドリンクはウィスキーを頂きます。
今年は会場がいつもと違うことや途中の旅程がうまく決まっていないこともあって胸騒ぎがするので、ウィスキーで落ち着きます。ウィスキーのブランドはシーバスリーガル 12年と書いていました。
おつまみもついてきておいしいです。サービスの品質高いですね。


夕食は和食と洋食が選べます。
今回は洋食を選びましたが、カレーっぽいお米の上に鳥が乗っていて東洋食というかんじ。
食器類も金属製だし美味しい。野菜スープも頼みました。


Unitedだと何食べているのかよくわからないチーズの化物みたいなのが出てきたりするのでかなり違いますね。(今年は改善されていたそうですが)
さらにハーゲンダッツのアイスクリームも出ました。


食事も終わり、映画も大したものがないのであまり無駄に時間を過ごさずすぐに寝ることができました。
成田からサンフランシスコまでのフライトは約9時間。

日付変更線を超えるので時間が巻き戻ったように錯覚しますが、夕方に飛びたって早朝につくので体感的には8時間圧縮される感覚です。
ここでの過ごし方で時差ボケが変わってきます。
方法としては二通りあって、徹底的に起きてそのままサンフランシスコの朝を迎える方法。日頃夜更かしするタイプの人はこっちがこっちが適用しやすいかもしれません。
日本時間の12:00がサンフランシスコで20:00なので、そこまで起きて早めに寝るという手もあります。

もう一つが寝てしまう方法で、現地到着時間の10:30は日本では2:30にあたるので、そこから逆算して日本時間で午後8時くらいに寝る事ができれば現地で朝を迎えることが出来ます。

今回は寝る方法を選択しました。おやすみなさい。

早朝起きたら朝食が出ました。飛行機ではあまり眠れたことがないのですが今回は割とぐっすり眠ることが出来ました。
これもANAの力(座席が広い)でしょうか?

ちょっと小さなお弁当とフルーツにヨーグルト。
軽食というのはもったいないくらいちゃんとしたものが出るので嬉しい。
これもUnitedだとかばんの奥底に入っていた1年前に買ったクッキーみたいなのが出てくるので随分と大きな差。


ANAさん見てます? 広告枠あいてますよ

食事も終わって一息ついたらアメリカ本土が見えてきました。


GoogleI/O報告会が6/25に九州で行われます。 ぜひご参加下さい
参加申し込み(無料)

Google I/O 2016渡航記 GDG Party編

$
0
0
飛行機内でアメリカへの税関申告書を記載します。税関申告書はAPCを使用する場合に必要ないのですがAPCはしょっちゅういろんな理由で使えなくなることがあるみたいなので記載して持っておくと入国で余計な時間を取られずに住むと思います。
必要な情報はパスポート番号とホテル名、州名(California)のほかは名前や生年月日といった基本的な内容と税金がかかるものを持ってきていないか、入国に制限がかかること(農場に最近行ったかとか)といった基本的なことです。
家族で移動するときは代表者が一人記載すればOK。

税関申告書を書き終わったころに最終着陸態勢になり、Mountain View周辺が見えてきました。
今年の会場はシェアラインアンフィシアターという屋外会場ですが、白いテントが特徴的で飛行機からバッチリ見えました。


空港では先着の飛行機がゲートを使用していたせいでなかなか降りることができず飛行機で足止め
今年は何かと飛行機がついていないですね。


やっとアメリカ上陸です。ここから入国審査が始まります。


アメリカ入国

初めての人はVisitorに向かいます、ESTAでの入国経験がありパスポートを書き換えていない人はAPCが使えます。
APCの場所は分かりにくいですが、VisitorとCitizenの間に設置されています。看板から言うとCitizenの方に向かうのでとても分かりにくいですね。

今回はAPCを使いました。APCを使う場合、キオスク端末でパスポートをかざして指紋や写真などを自分で撮影して、税関申告書に記載するような内容を端末で入力します。
そこで出てきたシートを受け取って対人の入国審査を受けます。
APCの機械はほとんど並ばなくていいですし、対面の入国審査も比較的スムーズ。APCのおかげで入国審査はかなり楽になりました。

質問事項で一般的なのは滞在の目的、場所、期間。 あと友人と一緒か、現地で友人に会うかなどもよく聞かれるポイント。
日本の航空会社運航便で入国する場合、一番最初に英語が必要になるポイントなので緊張しますが、入国審査の人も英語が苦手な人の対応にはなれているので焦らず質問の意図を探って単語で答えたら大丈夫です。
What'sかWhyから始まったらsightseeing
Howからはじまったらn Days
Whereから始まったらSan Franciscoとホテルの名前
Friendがふくまれたら No I'm alone.
という感じで、事前にシミュレーションしておくと楽です。

そのあと預け入れの手荷物を受け取ったら税関を通ります。
特別なものを持っていなければ通常税関はAPCの紙か税関申告書を渡すだけです。
最後にまたWhere... がくるので San Franciscoと答えればG Exitから出られます。(飛行機の乗り継ぎかここで出国するかの質問です)

あまりWelcome感のないWelcomeなので不安になりますが、ここを超えるとG Exitです。


サンフランシスコの入国は入国審査に大行列ができてひどい時は1時間以上入国に時間がかかっていたのですがAPCのおかげで15分位で入国できるようになりました。
APCに流れる人が増えたおかげで一般の入国審査も以前ほど混雑しないようです。

San Francisco市街地へ

今回は初日GDG Dinnerに参加するためSan Francisco市街地へ行きます。San FranciscoでSIMカードも入手します。
空港にもSIMカードは売っていますが割高料金となってしまいます。
AT&Tなら日本でSIMカードを入手しておけば空港でWi-Fi経由でアクティベーション出来るのですが今回はSIMもベンチ入手です。

BARTチケット購入

San Franciscoへ向かうためにBARTに乗ります。
BARTのチケットは購入するのがややこしいことで有名。 今回は初めてのアメリカであるGDG神戸の野田悟志さんに前提知識なし、ヘルプなし(途中横からちょっとヘルプが入りましたが)でBARTのチケットを購入する映像を撮らせてもらいました。
もしゲーム好きの人でしたら、この映像は飛ばしてBARTチケットの購入に自分で挑戦してみては如何でしょうか?



私は今回いろんな公共交通機関に乗るので共通で使えるクリッパーカードを入手しました。BARTのチケット同様最初にチャージして使用します。
日本で言うSuicaみたいなものでNFCを使用してタッチで入ることが出来ます。またCalTrainやMUUNIといったSan Franciscoにある公共交通金で共通に使えるカードで便利です。

空港のBARTの前にあるInformationで購入でき、デポジットとして$3取られます。SUICAのデポジットが500円なのでちょっとお安い。

空港からはSan Francisco方面への列車とMillbrae方面への列車があるので注意してください。
今回はSan Francisco市街地へ向かうのでSan Francisco方面への車両にのります。


BARTは案内も少なく車両も狭いので大きな荷物を持って乗るのはちょっと大変ですね。
BARTの車内では止まっている駅のアナウンスが自動で流れるのですが、聞き取りづらかったりするので降りる駅の前後駅を覚えておくと安心です。
San Francisco市街に向かう人はSan Francisco市街地はBARTが地下を走るので地下に潜ったらソロソロ と思っていただければいいかと。

私達が降りる駅はMontgomery St、モスコーニセンター最寄りのPowell Stの次にある駅です。結構広くて綺麗な駅で良かったです。BARTは比較的新しくて綺麗な駅が多いようです。

Civic centerからEmbarcaderoまでの間は駅間も短くひと駅程度なら15分程度で歩けますので降り遅れても慌てずに(ただしCivic center付近は治安に難あり)

BARTに乗ってSan Francisco市街地に到着。
San Francisco空港は日差しが入りにくいし、BARTはガラスがひどく汚れていたり、地下に潜ったりするのでSan Francisco市街地に出た瞬間に降り注ぐ日光のシャワーは強烈です。
湿気が少ないせいか、空気が滞留してる感じがせず、温かいところと涼しいところの差が激しい。


San Francisco市街地観光

今日は18:00からGoogle San Franciscoオフィスでディナーパーティーです。
それまでの間SIMを買ったり肉を食べたり、短い時間ですが精一杯楽しもうと思います。

最初にホテルにチェックインして荷物を預けます。
今晩のホテルはGDGに準備していただいたのですが、本当に素晴らしいホテルで驚きました。


降りたら早速ホテルにチェックインして荷物を預けT-mobileに向かいます。昨年はAT&Tにしたのですが今年はT-mobileに戻してみました。

以前存在した1日$3のお手軽プランがなくなっていて、何故かオンライン上にあるSIM割引のプロモコードも店員がわからんとか言い始めて使えなかったので結局1ヶ月3GBまでの音声つきプランになっちゃいました。 $40+税で$49 一週間しか使わないのでちょい高いね。(後で気がついたのですが電話番号がないと意外と不便なので結果オーライでした)
カメラの性能やバッテリーの性能を考えて今回San FranciscoではNexus6Pを使います。

T-Mobileが開通したのでPowellにあるTED'sステーキハウスに向かいます。
ここのステーキは比較的安くてアメリカならではのステーキが食べられるので重宝しています。

脂身が少なく引き締まった骨付きステーキ肉は本当においしく、日本にもこういう肉が広まってくれたらと思います。
サラダとじゃがいも、ぱっさぱさのパンが付いて$18
チップを$0にするととたんに店員の対応が雑になるけれど気にしたら負け。
アメリカでは図太い神経と、雑さを許容しあう寛容さが必要ですよね。


T-mobileとかで意外と時間を食ってしまったので買い物は諦めて、ホテルで体制を整えGDG DinnerのあるGoogle SFオフィスに向かいます。
Google SFオフィスはオークランドに続くベイブリッジの麓にあり風光明媚な場所です。
ホテルから歩いて20分ほど。
San Franciscoといえばゴールデンゲートブリッジのほうがアイコン的ですがより近代的なベイブリッジも綺麗です。


オフィスの近くにはmozillaのオフィスもあるため記念写真を撮ってきました。
コミッターの名前が刻まれたFirefoxのロゴが未来的かつ威厳を感じさせてくれます。


GDG Dinnerでは食事とお酒でパーティーしました。オフィス内撮影禁止なので写真がないのが残念なのですが、世界中のGDGオーガナイザーと食事とお酒を楽しみます。


ここでは世界中の人とおみやげの交換も行いました。私が持って行ったのは昨年好評だったハッピーターン、今年は焼きとうもろこし味です。
世界中の人にハッピーターンを渡したのですが、殆どの人がとても良い反応でした。
そもそも、お米をベースにしたお菓子というのが世界的に見ると珍しいのではないかと思うのですが、ハッピーターンの魅力は世界共通なようです。

ところでこのシチュエーション、ゲートブリッジはCaliforniaの強い直射日光を受けて明るく輝くのですが、自分たちはビルの影になってしまうので写真をとっても自分が真っ黒になるか背景が真っ白になるかのとても難しいシチェーションです。
今回、光の飽和に強いα7sで撮影を試みたのですが、やはり解決せず。


そういえば2012年にGoogle I/Oに来た時はSONYのミラーレス一眼NEXシリーズのユーザーが圧倒的に多かったのですが、今年はリコーのTHETA、そしてCanonの典型的なデジタル一眼レフユーザーが増えているように感じました。
画質を求める人はCanon、革新さを求める人はTHETAを選んでいるという印象。
しかしながら、α7sはCanonのAPS-C一眼レフよりもかなり小さく、やはりこの軽快感は捨て切れません。
外が暗くなってきたのでそろそろホテルに戻ります。


帰りはLyftで帰宅しました。世界的にはUberのほうが有名ですがLyftはUberと直接競合するタクシーサービスです。
フロントにピンクのひげを生やしているのが特徴らしいですがこの車にはそれはついていませんでした。

明日からはGDG Summitそして、Google I/Oとタフな日程が始まります。頑張ります。
おやすみなさい。
といいつつ、寝付きが悪くて結局仕事をしながら寝ていました。
現地時間では深夜1時を回っているのですが日本時間ではまだ夕方の5時。時差ボケがじわりと効いてきてます。

Google I/O 2016渡航記 GDG Summit + IntelParty編

$
0
0

GDG summit

今日はGDG summitが開催されます。

お気楽なPartyと違って、セッションと幾つかの討論などもあるSummitは体力が必要です。
しかしながら、眠気がかなり強く残っています。
今年のGDG summit会場は今泊まっているホテルで開催されるため移動がないのがうれしいです。シャワーを浴びて身なりを整えたらホテルをチェックアウトして荷物を預けた後1Fで朝食を取ります。
朝食はフルーツやパン、ソーセージやベーコンなどを取りに行くスタイル。かなりおいしい食事で大満足です。


最初にGDGの現状とTensorflowやFirebaseなどのセッションを受けました。
特にTensorflowについては単純な計算式の組み合わせでいかにして高度な計算結果を求めるかについて図式を使いながら丁寧に解説されていて今までのAI系の話の中でいちばん概略が分かりやすかったです。

GDGに関してはOrganizerの数が増え続けて現在2000を超えているとのこと、Chapterの数が約622なので概ね1Chapterあたり3人のOrganizerがいる計算。
九州では二人のOrganizerでまかなっているのでそろそろ3人目を考えたいです。

その後はFirebaseを使ったIoTコードラボです。
Arduinoのような小型のチップにWeb上からPushを送ってモーターなどを駆動させます。
これをレゴブロックで作った家に組み込むという内容。

レゴブロックのマニュアルって基本的に文字がなくて絵なんですね、言語があまり通じない人同士でも協力してレゴブロックを作っていけるというのが面白かったです。これは言語を超えたコミュニケーションの手法としても勉強になりました。(しかしレゴ側の作業量が多くてFirebase側が疎かになってましたが)


昼食をとったら午後はアンカンファレンスに参加します。セッションの内容はあらかじめ投票で決められたもので2回の時間枠をつかって好きなセッションに行くというもの。

1回めはGDG用に作っている非公式のツールについて、どのようなものがあり、どのように貢献しているかについてのセッション
現在非公式ツールの日本語化がまだ完璧ではないため、翻訳をコミットしました。
オープンソースへ貢献する上で最初の一歩に日本語化を行うというのは敷居が低くて良さそうです。
ソースコードをコミットするのも言語を超えている部分があって結構面白いです。(コミットログは英語ですが)

2回めはイベントを開催する上でスポンサーを求める方法について議論しました。

Googleや現地の企業から支援を受ける方法、どのような支援があるか、それらの支援を受けることによるメリット、デメリットについて知見を得ました。
スポンサーを得るか得ないかはイベントを行う上で毎回重要な指針になりますが、スポンサーを出したいと思える規模のイベントを実現することも大事ですね。

移動

GDG Summitを終えるとGoogle I/Oの登録を行うためにマウンテンビューへとバスで移動します。


MountainView周辺の雰囲気はこんな感じ
山、見えますね


夕方にSan FranciscoからMountain Viewに行くのは初めてでしたが、渋滞はSan Francisco市街地周辺とSan MateoBridgeあたりの橋がある付近、Mountain View周辺だけで17:10にSan Franciscoを出発し18:10にMountain Viewに到着しました。
例年は逆方向、Mountain ViewからSan Franciscoへ向かう旅程で2時間弱かかっているので約半分の時間で移動できていることになります。

登録

MountainViewに到着しました。
登録はアンフィシアターの入り口で行います。
モスコーニセンターの時と違ってこの日は登録受付口の数が多くてスムーズに登録を終えることができました。

登録時に例年と同様に記念品をもらいますが、今回の記念品はCardBoardに水筒、サングラスと日焼け止めそれらをサバイバルキットという名前で配っていました。今回に限って言うとCardBoard以外は本当に生き延びるのに大切になりそうです。
その場で写真をとって名札に印刷する方式なのですが、意外にもサクサクと印刷が終わってほとんど待たされませんでした。
しかし、カメラが単なるWebカメラでしかも逆光だったので顔が真っ黒になってしまいました。 これじゃ誰だかわからないじゃん。

CardBoardは見た感じ昨年のものとほとんど変わっていないようです。色が白くなっていて汗ジミが目立ちにくそうです。ちょっとおしゃれになって感じ。

Intel Party

今日はこれからIntel Partyに移動します。Intel Partyは今年で3年目、Google I/Oの前日に開催されるためZero Dayなどとも言われています。Intel Partyはサンパルノで午後7時から行われます。移動手段がないのでUberを使ってみました。

やってきた車は先代のプリウス、大人3人がキャリーバッグを3つも持ってプリウスに入るのか心配でしたがパズルのように荷物を入れ替えてなんとか詰め込むことに成功。

Uberのドライバーが来たら何度も電話をしたのになぜ出てくれないのか?警察が多くてピックアップが大変だったという指摘を受けました。
その時気づいたのですがUberを登録したのは日本で登録されている電話番号も日本。
しかしながら、日本のSIMが入ったNexus5は通信を行わないように電源を切ってカバンの奥底に眠らせたままです。
Uberを使用するときは現地SIMを登録して現地の電話番号を登録しておいたほうが良いようです。
しかし、ちょっと謝ったらすぐに許してくれてそれ以降はずっとフレンドリーでした。

18:37にMountainViewを出発してIntel Partyに到着したのは19:10。
Uberの料金は走行距離18.73kmピーク料金で1.3倍になっており料金は$20.43でした。

Intel Partyは19:00スタートだったはずですが、着いた時点ではまだ会場が開いておらず行列ができていました。


申し込みが開始されたので中へ。直前にIntelチームがatom撤退を発表していたので今後のIntel Androidチームがどのようになるか興味深かったのですが、これといって特にアナウンスはなく、会場内にはAtomのポスターも飾られていました。
Intelとしては安売りバーゲン状態だったAtomを捨ててCoreシリーズに集約するのでしょうか、AndroidにおいてAtomはそれほど注目されることはなかったですがWindowsの低価格タブレットではほぼ市場を独占している状態だったので今後の影響は少なくないはずです。

その関係かどうかわかりませんが今回は例年先着組に配られていたプレゼントはありませんでした。
一昨年はタブレット、去年はスマートフォンだったので今年はウェアラブルを期待していたのですが残念です。かわりに抽選でスマートフォンやウェアラブルデバイスが当たるイベントをやっていました。
また、ブースで話を聞いたりするとチケットが貰えてチケットの数に応じて先着順のプレゼントがあるというのを今年もやっていました。
例えば200個集めるとIntel Edisonがもらえます。200個も集めるのは容易ではないでしょうがうまくブースを回ったり帰り際の人と仲良くなれば集めることもできるかも。


Leap Motionを使用したUFOキャッチャーもありました。無料でしたが人がかなり並んでいたので断念。



ビールの種類を注文するときにあなたのおすすめは?と聞くと
スパイシーなのとスイートなのどっちが良い?と聞かれたのでスイートなのをお願いしたら
なんとビールの中にシロップのようなものを入れた挙句ハーブのようなものを載せたカクテルが出てきました。
かなりの量のシロップが入ってビールがピンク色に染まっています。

しかし、見た目に反してデロデロに甘いということはなく、カクテル的な甘さと香りでちゃんとビールらしい風味も残っていました。
これは日本でも若い人や女性に受けそう。

Intel PartyスペシャルのInovative Aleも頼んでみました。
こういうイベントにかけた名前のお酒は面白いですね。


なんと黒ビールでした。
私、黒ビールは苦手なのですがあまり黒ビール特有のもったり来る感じがなくおいしく飲むことが出来ました。


Intelパーティーが偉いのは食事もお酒も本格的で美味しいこと。しかもフリーです。
I/O参加者という条件付きながら無料のイベントでこの大盤振る舞いはすごい。
食事に関してはI/Oよりずっといいものをゆっくりと食べることができます。 食べ終わったものも取りに来てくれるし本当に大切にされているって感じがする。


DJブースではインテル入ってるタッチパネル式のDJキットが使用されていました。
コレにかぎらず本気でやるならインテルというのがクリエイティブ業界では定着しているのでAtom撤退は本当に残念。



Intelが毎回I/O会場に連れて来ていたドロイド3家族。これも今年まででしょうか?


抽選はChromeBookやZenFoneZoomが配られていました。最後のデバイスはウェアラブルと言っていたのでTAG HEUERのウェアラブルデバイスな可能性があります。しかし流石に夜も深くなってきたしホテルのチェックインも出来ていないのでそろそろ帰ることにします。


その後aloft santa clalaホテルへUber-XLで移動。Uber-XLはちょっと大きなUberで3列シートのSUVが来ました。
日本で言うとミニバンと言う感じでトランクにキャリーバッグを入れるには3列目を倒す必要がありフル乗車+キャリーバッグは収まらないのに注意が必要ですね。
夜中だけあって高速はスイスイ進みますが、日本の高速道路ほど地面がフラットではない上にアメ車特有のふわふわとした乗り心地で車の進行方向が定まらず運転しづらそう。

Aloft santa clalaホテル

そうこうしているうちにaloft santa clalaホテルに到着しました。
例年San Franciscoの馬鹿高いホテルに愛想を尽かしていて、今年はMountain Viewだから安いだろうと思っていたら、意外とお値段お高め。特に今年はルームシェアを指定ない分余計に金額がかかります。 苦しい。
しかし、部屋を見てルームシェアしなくてよかったなぁと思いました。
というのもトイレには壁自体が存在せず、洗面所と直結。
洗面所と寝室間には壁こそあるもののドアはなく入り放題覗き放題状態。
部屋自体は枕が2つあったりベッドの証明が左右に設置されていたり複数人泊まることを前提のはずなんですがアメリカ人はオープンなんでしょうか?
あと防音はあってないようなもので外や他の部屋の音がよく響きます。

机の上にコンセント2つ、USB給電器2つの電源ボックスが設置されているなど電源周りは割といい感じ。
USBの出力も良いようでNexus6がぐんぐん充電されていきます。


荷物をまとめたりシャワーを浴びたり充電やらしていると1時を超えてしまいました。
明日はいよいよGoogleI/Oの初日。ハイライトとなる基調講演や豊富なセッション、そして夜にはAfterConcertが開催されるはずです。
現地からの中継を行うために6時おきなのでそろそろ寝るとします。

Google I/O報告会が6月〜7月にかけて全国で行われます。
詳しい開催場所と日程はGoogle developers Japanを参照して下さい。
Google I/O報告会の福岡会場は6/25に行われます

Google I/O 2016渡航記 I/O初日編

$
0
0
6時に英語の会話が聞こえたので何事かと思ったら目覚まし時計で指定の時間にラジオが再生されるというものでした。この寝起きは悪く無いですね。

I/O会場へ

諸々準備を整えて7時のバスで出発です
I/O会場へは実質的に車以外の交通手段がないのではたして基調講演に間に合うんでしょうか? いろいろ不安ですね。

バスは日本で言うところのハイデッカー観光バスという感じ。
アメリカでは日本ではほとんど見かけなくなったボンネットバスなども走っていますがそれに比べてかなり大きいです。
朝一で移動する人は少ないようでガラガラとしていました。


移動を開始するとこんな時間なのにインターチェンジ付近では渋滞が発生していました。
Mountain View周辺の朝は渋滞とかないんじゃないの?と思っていたのでこれはちょっと意外でした。
逆に会場付近はスムーズ。大型の駐車場をシャトルバスの乗り降り場にしてシャトルバスを優先していれていたこともあるでしょうが、すぐに駐車場に入れて拍子抜けしました。

結局会場に到着したのは7:16、早いなんてものじゃありませんね。


会場に入るには簡単な金属チェックを行います。
といっても空港ほど厳密にやっている感じではなくちゃんとやっているよとアピールしているだけな感じ。

朝食はベーグルとドーナツそしてフルーツの盛り合わせです。
I/Oの食事は例年クオリティがイマイチなのですが意外にもおいしい。ベーグルにはチーズが良く会いました。


去年は圧倒的に量が足りていなかったコーヒーサーバーも今年はすぐに見つけることが出来ました。混雑している感じもないしとても良い。
アメリカのコーヒーはまずいなんて言われますが私はとても好きで毎回飲み過ぎてしまいます。

モスコー二の時と違って椅子はなく立食方式です。


今日本ではI/O ExtendedをやっているのでそことYoutube Liveで繋ぎたかったのですが、机がないうえにものすごい人でPC出してられない状態だったのでスマートフォンでも行えるGoogle Hangoutを使って福岡会場と現地中継をつなぎました。
中継途中で日本からの参加者にインタビューしたりインドGDGの人から声かけられたりと楽しかったです。
反省点としては会場はすごくうるさいのでイヤホンが必須ですね。途中で気がついたのですが最初からつけておけばよかったです。

9時の時点ですごく暑く体中の水分がジリジリと奪われていくのを感じます。

しかし、オープンスペースのおかげでカラッとして気持ちよく、体感的にも開放感があって楽しいです。オープンスペースで行うのは心配したけれど雰囲気の点では大正解。
特別な感じがあって気持ちが良いです。

会場にはGoogleの自動運転カーも置かれていました。

車内はこんな感じ。コンパクトな車体なのにハンドルがなくてとても広々としています。
ただアクセルとブレーキらしきものは置かれていました。ブレーキはともかくとしてアクセルはどのようなときに使うのでしょう。ちょっと不思議ですね。


それにしても芝生広場があったり、ストアがあったりなんて広い会場なのでしょう。
端から端まで歩くだけで結構大変です。太宰府園くらいの広さがあるんじゃないでしょうか


基調講演の開始時間が近づいてきてアンフィシアターにはいるための行列ができはじめました。


基調講演

アンフィシアターは野球場の外野席のような雰囲気です。前日の登録時点でおおまかな場所がアサインされていて入場時も大きな混乱はなかったです。


会場の雰囲気を撮影していたらa2cさんとアダムロッカーさんに声をかけられとなりに座らせてもらいました。


発表が始まる前にスマートフォンでペンキを投げつけられるサービスが公開されました。
会場でスクリーンに向かって皆がスマートフォンを振りつけるのはなんとも異様な感じ。現実にその場にいる人達がWebを介してリアルタイムでつながりあう、最近Googleが力を入れようとしている分野を体現しているように感じます。


スクリーン上には世界中を巡る紙飛行機が表示されました。
詳細がちよくわからないのですが、世界中からスマートフォンで紙飛行機を飛ばすことができるようで、リアルタイムレンダリングしているようです。途中ちょっと処理が遅くなってフレームレートが下がっています。


それを見た観客も本物の紙飛行機を飛ばし合い会場は奇妙な熱狂と一体感に包まれてきます。


観客席を大きくまたぐようにはられたワイヤーをつかった弦楽器による演奏が披露されました。
細かくて気が付かなかったですが、よく見ると会場をまたぐように細いワイヤーが張られていてコレを弾くことで音楽が奏でられています。
アンプを介しているのか生なのかはわからなかったですが、不思議な演出でした。


基調講演はいつものAndroid,Chrome,その他の流れではなく、人工知能から始まる異例の内容。

YouTubeでは収録されていませんが、会場では笑い声や歓声が結構な頻度で発生していました。


あと会場に鳥が巣を作っているのかずっとピヨピヨピヨという鳥の声が響き渡っていてなんとも言えない牧歌的なムードが出ていました。

具体的な内容はYoutubeを見てもらうとして、ざっくりとした感想

AIについて

AIについてはGoogleがすごい力を入れているなというのを感じています。
とくにGooglePhotoの認識力は既に実製品で体感しているのでAIが今後大きなビジネスになるのは疑いようが無いです。
チャットツールAlloとビデオ機能Duoについて、チャットとビデオ通話は現在すでにHangoutとして提供されていてLINEやFacebookメッセンジャーほど一般的ではないにしてお全体的に洗練されてきていて利用者も増えていたように感じます。ブランドを育てるという意味でも無理に名前を買えない方がいいともうのですが、利用用途が同じものに対して別ブランドにした理由はよくわかりませんでした。
しかし、ビデオ通話を基調講演で実際にやってしまうのは覚悟が必要だったろうなぁと思います。
通常、この手の発表では事前に録画した映像を使ったフェイクを使ったりするのですが、今回の基調講演では本当にライブでやり、娘からの挨拶をガチャギリするというトラブルw。 家に帰ってから修羅場だったんじゃないでしょうか?

Google Home

GoogleHomeから漂うなんとも言えない愛らしさというか、NexusQ感はなんなのでしょう。
正直なところ本当に発売できるのか不安で仕方がないし、なんかあんまり成功する感じがしないです。
この手の製品はいつもすごく魅力的なデモと実際には機能しない製品というのが定番化していますがそろそろ実現しないですかね?
見た目については消臭力じゃん というのが指摘されていました。デザインはNexusQのほうが尖っていて好きです。

しかし、こういうキワモノハードこそGoogleのような会社が出して欲しいですね。
利用用途がわかりきってビジネスになることが見えている商品よりこういうなにか新しい物を作れるのではないかと想像させるハードこそGoogleに出してほしい商品です。

発売できたとしてもはたして日本発売がされるかすごい心配。Chrome CastやNexus Playerは日本でも発売されたので期待したいのですが、第二世代Chrome Castは発売が遅れましたし、昨年中と言われていたAndroid Autoも日本に入ってきていません。人工知能による音声解析とかは特に日本対応が難しい部分なので日本だけ販売しないんじゃないかという心配もあります。似た製品のAmazon Echoも日本で発売される気配がありません。
しかし開発用に英語オンリーでいいから技適だけ通して同時発売を期待したいです。

OnHubあたりと連携して、家に一人しかいないときはプライベートなメールの通知も行い、複数人いる時は複数人に関係する通知のみ伝えるみたいなでき方がするととても便利だと思うのですが。

Android N

Nについてはプレビュー版が既にでていて新しい話はそれほどなかった気がします。
名前はやっぱり公募するようです。
NでVRに関しての機能が追加されたのが数少ないサプライズでしょうか、

VRについて

Project Tangoについての発表がなかったのがやや残念ですね。今回のセッションではVR関連のセッションがかなり増えているのでてっきり基調講演でProject Tangoについての言及があるかと思ったのですが間に合わなかったのでしょうか。
代わりに出てきたのがDaydreamというVRのプラットフォーム。
ソフトウェアとハードウェアの両方でより没入感高いVRを目指すとのこと。
Daydreamという名称どうにかならなかったんですかね、昔からのAndroidエンジニアであればかつて充電台に載せた状態で実行されるスクリーンセイバーがDaydreamという名称だったのを覚えている人も多いはず。
実際のところは充電中に独自アプリを作りたいというニーズはあまり一般的ではなくまるで話題にもならなかったのですがまさか、Android開発チーム内でも忘れられてしまったのでしょうか。
対応ハードを出すメーカーの中に日本メーカーが入っていないのがなんとも残念ですね。

Wear2.0

AndroidWearが登場して2年を迎えました。当初おもちゃだったWearもバージョンアップを繰り返して次第に使いやすく実用的に育っています。
もともとAndroid4.4ベースだったAndroidWearも今では6.0ベースとなりました。
つまり、AndroidWear自体は3つのAndroidのメジャーバージョンアップを超えてきています。
しかも、なかなか最新版がこないスマートフォンと違いAndroidWearはどのメーカーに対してもバージョンアップの対応が早いのが嬉しいところ。
にも関わらず、今回は2.0と控えめなバージョンをつけてきました。
これは今までにない大きなバージョンアップであることを示しているのか、それともそろそろ対応ハードが切り捨てられていくことを意味しているのかどっちでしょう。 どっちもかも知れません。

Wear2.0で最初に語られたのがWatch Faceについて、Android Wearでは比較的初期のバージョンでWatch Faceに対応して、その後Watch Faceで簡単なアクションが可能になるなどの機能が追加されてきましたが、今回のバージョンアップでは他のアプリからデータを受け取ることができるようになります。
情報の送信側は情報を抽象化して送りWatchFace側で描画を担当するという組み合わせが面白かったです。
Watch Faceを作る上での悩みの種として、天気予報や未読メッセージ数などの情報をWatch Faceで表示したいけれど、ほしい情報はユーザーにより違うため、ユーザーによっては不要な情報を見せてしまうことになるというのがあったので、そこをAndroidらしくうまく解決してきたなぁと思います。
SONYのSW2にも似たような機能はあったのですが、SW2はアプリ側が矩形にデータを描画して、ユーザーはそれらをブロックのように組み合わせることでWatch Faceを作る仕組みだったのに対して、Wear2.0ではデータを抽象化して送り、受け側のアプリが自分に適合するように処理する仕組みとなっており、Watch Faceの世界観を崩さずにカスタマイズ性を提供できるのではないでしょうか?この途中の階層を抽象化することで疎結合にする仕組みは暗黙的IntentのようでとてもAndroi的だと思いました。

Watch Faceはユーザーが操作すること無く見ることができる画面で、ここにほしい情報が表示されることでウェアラブルの使いやすさが一気に改善します。(この点においてAppleWatchは大きく出遅れておりそれがウェアラブル全体の評判を落としているのが残念です)

その他Standalone機能やキーボードについてはこれにより出来ることが大きく増えるという感じはしませんでした。
スマートフォンがなくても直接ネットワークと繋がると言ってもLTE内蔵のAndroidWearは多くないですしそれほど受け入れられている感じもしません。
それより、本音のところは「Android」スマートフォンがなくてもネットワークに繋がるようになったということでしょう。
つまり、iOSユーザーであってもWearにアプリをインストールしログインしカスタマイズできるようになった。そう見ることが自然な気がします。

しかし、一方でそろそろスマートフォンを使わずにWearのみで生活してみたいという気持ちも出てきています。
Wearはスマートフォンよりも現実の生活を阻害しないように感じていて、移動を楽しく生活をより豊かにしてくれる予感を感じています。

Android Studio 2.2

早い、早いよGoogleさん
ついこの前2.1がでたばかりなのにもう2.2です。
しかし、最近のAndroid StudioはCanary channelでも完成度が高く十分に業務レベルで使用できたりするのでこのスピード感は驚くばかりです。
しかも、去年のように夢ばかり語るのではなく今すぐ使えるというのがすごいですね。早速試してみたいです。
条件付きとはいえBuildが早くなるのは助かります。Android StudioはBuildが重たすぎて作業に支障が出てしまい、結局15inchのMacBookProを購入して物量で解決したのですが持ち運ぶ時はつらいなと思っていました。もっとBuildが軽くなって 質量的にも軽いマシンで作業できるようになると嬉しいです。

Firebaseについて

Firebaseは機能てんこ盛りになりましたね、Google Cloud Platformとのブランド分けがイマイチわかりづらくなった気がします。FirebaseのFirebaseたるところってなんでしょうね?
モバイルアプリ開発者が使用する機能もFirebase化したことで注目度は上がると思います。

Progressive Web AppsとInstant Apps

アプリとウェブがお互いに近づいてきていることを感じます。
うちのサイトもhttps化してちゃんとProgressive Web Appsを追いかけたいなぁ
Instant Appsはイベントアプリのようなユーザーが恒常的に使い続けないアプリでは特に対応必須になると思います。

Tensor Flowについて

TPUについてはいろいろ考えさせられるところがあります。
ソフトウェアとハードウェアの領域争いは長い歴史の中ずっとシーソーのように揺れ動いていましたが、ここ最近ハードウェアの振り返しが大きくなってきているように感じます。

全体的に

基調講演の時間自体は例年と同じだと思うのですが、今年の基調講演は凄くボリュームが有ったように感じました。
AndroidNやAndroid Studio2.1、Material DesignのアップデートがI/O直前にプレビュー版が公開されていて今年のI/Oではこれといった発表はもうないのではないか? と危惧していたのですが杞憂でした。

基調講演が終わって

今年も去年同様、おみやげのアナウンスはなかったのですが、去年はこれで終わり? おみやげ無いの ひでー(実際には直後にNexus9が配られるメールがあった)という感じでしたが、今年はこの内容ならおみやげ無くてもいいよね と感じました。

実のところ、おみやげについては新製品のNexus7やNexusQを配った2012年を除くと、既に発売済みの製品を配っておりその技術に興味がある人なら既に持っているし、その技術に興味が無い人にとっては貰っても微妙という感じで正直だったらI/Oを充実させるか料金を引き下げて欲しいと思っていたのでおみやげを終えるには良いタイミングだったのではないでしょうか。(本音を言うとGoogleHomeが欲しかった)

文句をいうなら参加受付をする前におみやげがない旨を告知して欲しかったです。そうすればおみやげ目当てで参加する人がいなくなってもっと開発者が参加しやすくなっていただろうし、おみやげ目当ての人ががっかりすることもなかったはず。

さて、基調講演が終わったらランチタイムを挟んでセッションが始まります。

アンフィシアターを出ると あれ?
なんだかさっきまで行けなかった場所が開いています。しかもむちゃくちゃ広いです。 もともと受付の段階で広いと思っていたのに、公式アプリで調べるとさっきまでいたのはI/O会場のほんの一部でしか無くてセッションの殆どはこの開かれた区域で行われるようです。
この感覚FINAL FANTASY3の広い世界を回ったと思ったら実は広大な世界に浮かぶ小さな島に過ぎなかった という演出に似てる(超大げさですが)

広い空間にセッション会場が配置されていてその中に様々なブースが点在しているという状態。
セッションはYouTubeでも公開されるし強く興味を持ったものを除けば今回のI/Oではブース巡りを中心に行おうと思っています。

スマートフォンで産業用ロボットを操作してペンキを突きつけるロボット(なんと贅沢な)



WearのブースではTAG HEUERを含めた各種Wear端末がおいてあっただけでなく、Pebbleなどの競合製品やWear2.0が動く端末もおいていました。
Wear2.0に関して言うと端末自体の性能も有るかもしれないけれど、今使っている端末より動きがなめらからで使いやすくなっている印象。


もちろん、カシオの端末もありました。バッテリー持ちが良い私の中では今一番注目しているAndroid Wear端末です。

それにしてもWear端末増えましたね。

MOTO360が出た時は衝撃的だった丸型液晶も今では一般的になっています。


TAG HEUERの15万円なウェアラブル。
正直、これに15万円は出したくないなぁ、正直MOTO360のほうが高級感を感じます。



セッション

見て回ったセッションは次の通り

What's new in Android

正直うーん という感じ。 プレビュー版をウォチっている人にはそれほど目新しい情報はなかったように思います。


Designing ofr driving

Android Autoの最新情報として、ワイヤレスに対応しました っていうのと、スマートフォン単体で動くAuto(つまり、単にスマートフォンを車の中で使いやすくするアプリ)というのは新しく感じました。
あと、単純なAndroid Autoではなく、純粋なAndroidが内蔵されたプロダクトも紹介されていました。本命はこっちですね。
しかし、問題だったのはそれ以降の内容はAndroidAutoアプリの作り方で、これ自体はAndroidAutoが公開された時から変わってない特に新しくもなんともない内容でした。


After concert

その後はすごい人達とビールやワインを飲みながら話をしていました。
バドワイザーっていう軽いビールがあるのですがバドライトっていう更に軽いビールがあって驚き。
日本で言うと発泡酒的な扱いでしょうか?
もちろん、ちゃんとした地ビールもありました。おいしい。

次第にアンフィシアターのほうが騒がしくなってきました。
アンフィシアターではAfter Concertが行われていました。
Concertは演奏の間の休憩時間だったようですが、観客席を順番にスクリーンに映し出していて盛り上がっていました。
LEDで点滅する棒やらメガネやらを配っていて暗闇の中に光輝き綺麗。


そんなこんなで初日は終了、バスに乗ってaloftホテルに戻ります。

Google I/O 2016渡航記 I/O 2日目編

$
0
0
今日も英語ラジオで目覚めです。
以前自宅でラジオ目覚ましを使っていた時は電源がつくときのリレー音が響いてそっちで目覚めてしまうことが多かったのですがこの目覚ましはそういうこともなく音量がじわっと上がってきていい感じです。

朝方、今日は寒くなるから厚着してこいよ ってメールがGoogleから届く。
ほんまかいなと思いながらも下着を重ね着しておきます。

昨日はブースをメインに回ったので今日はセッションをメインに回ろうと思います。
今日はWearのセッションも多くて楽しみです。
話を聞くと昨日はセッションにかなり並んだけれど入れなかった人が多いそうです。
参加者の割にキャパシティが足りていなかったのでしょう。
Google I/Oでは例年(特に去年)キャパシティ不足が問題になっていましたが、今年も同様なようです。
特に初日のセッションは皆やる気にあふれているのでセッションへの参加者が集中する傾向にあるようです。
どのセッションが自分にとって絶対に見逃してはいけないかというのを決めておいてどれに参加して、どれは捨てていいかを予め決めておくほうが良いと思います。

私の場合、Androidの新技術と特にWearのセッションについて集中しようと決めていました。
それ以外は最悪YouTubeで見ればいいのでブースを回ったり、他の人と話す時間、次のセッションに参加するために並ぶ時間に割り当てることにしました。

昨日はWhat's new Androidについては巨大なアンフィシアターでの開催、Autoに関しては比較的大きなブースの割に参加している人が少なく余裕で座れたのでよかったのですが、今日は朝1のWear2.0についてのセッションを聞くので万全を期して今日もまた7時のバスで移動します。

アンフィシアターの前で待たされた昨日と違ってセキュリティゲート前の道路で待ちます。昨日より寒いのは寒いのですがやはり直射日光が当たる部分は暑く、日本のような底冷えをする感じではありません。

朝食のメニューは昨日と変わりません。多くの人は甘いドーナツを狙っていましたが、私は昨日美味しさに気づいたベーグル目当てです。人気が少ない分獲得は容易。

ちゃちゃっと朝食を済ませたらブースへ向かいます。
ブース付近では屋外で椅子に座ってPCを開いている人たちが居ました。屋外で作業を行う姿は日本ではあまり見かけないですが、アメリカではまぁまぁ見る気がします。しかし、この強い直射日光下においてノートパソコンの液晶画面がちゃんと見えているのだろうか不思議です。


セッションが始まるのが9時からなので待っているのですが、昨日とくらべて風が冷たくなっている気がします。
一方で直射日光を受ける側は直射日光を受けてとても暑い。

セッション

What’s new with Notifications in Android N and Android Wear 2.0

Android Wearの話かと思ったらAndroid Nの話も半分入っていました。
WearのフィードバックがNにも反映されている話からスタートです。
Androidはとても早い時期からNotificationに力を入れていて、バージョンアップごとに機能が追加され続けていますが、今回のNではアプリを起動せずにNotificationで操作を完結する部分、情報を管理する部分に力を入れてきました。
Notificationの最適化はWearの最適化にもつながるのでこのセッションでNとWearをまとめたのは重要なGoogleからのメッセージだと思います。
Wearの話で言うとMaterial Designが新たな形で採用されて通知が全画面表示になりました。
既存の通知はごちゃごちゃして見やすさの面でも美しさの面でもイマイチだったので地味ながら嬉しい。
操作が上下左右だったのが上下方向に統一されたのは使い勝手の面でどうなのか実際に試してみたいところです。


What's new in Android development tools

アンフィシアターの広大な画面でのライブコーディングは迫力満点。会場が広いのでセッションに入れないということもなくて良かったです。
しかし、地味なコーディングを大画面で行うのはなんともミスマッチで面白いですね。一度あんな画面でコーディングしてみたいものです。
Androidの新技術自体は開発者向けプレビューで紹介されていることがほとんどだったので驚きは少なかったのですが、開発ツールは新しいUIデザイナーなど魅力的な内容が多かったです。


What’s new in Android Wear 2.0?

Wear2.0ではついついキーボード入力に注目が行ってしまいそうですが、もっとも重要なのはComplications APIだと思っています。
これにより、ユーザーが導入したあらゆるアプリが、ユーザーが選んだあらゆるWatch Faceと連動する。
出来る操作が限られているスマートウォッチにおいては眺めるだけで完結するWatch Faceにどれだけの情報をどのように表示できるかが重要です。
例えばSonyのSmart WatchではアプリがAndroidのホームスクリーンウィジェットのような機能があり、それらを組み合わせることでWatch Faceを作ることが出来ました。
この機能は当初は存在せずバージョンアップで追加されたのですが、この機能が追加されて天気予報や温度をスマートフォンを開くこと無く確認できるようになりWearの使用率がまるで変わるほど便利になりました。
一方で見た目に関しては複数のアプリが並んでいる状態になってしまい、おしゃれとは言いがたいという問題がありました。
Complications APIはデータ提供元はデータのみを提供し、最終的な描画をWatch Faceが描画することでWatch Faceの世界観を潰すこと無く情報のチラ見を実現できそうです。


日本人大集合

今日のお昼は日本人大集合です。
今年はI/Oに参加している技術者が7,000人にもなるとのことで日本人も多く参加しています。
ランチタイムに日本人で集まって集合写真を撮るというシンプルなイベントですが、今年は50人以上が集まって記念写真を撮影しました。
I/O折り返し地点でこれまでの流れや空いているセッションの情報交換などが行われました。

午後のセッション

Android Wear 2.0: Making Watch Apps more Standalone

Android Wear 2.0ではStandalone機能が追加されました。これまではアプリをインストールするにはスマートフォンにホストアプリを入れてホストアプリの中に入っているWearアプリをWear端末にインストールするという仕組みで、通信を行うにもWearはスマートフォンと通信を行い、スマートフォンが外部通信を行っていましたが、StandaloneではWi-Fiやスマートフォンを中継するなど、様々な理由で利用して直接Wearアプリが外部と通信することが出来るようになります。
しかし、この機能で一番大切なことはWearからアプリをインストールできるようになるということ、さらに言えばiOS端末と接続されたウェアラブルでもアプリをインストールして機能拡張できるようになったことでしょう。
1 Wear開発者としてとてもワクワクさせられます。
現状ではLG Urbane 2nd Edition LTEとHuawei Watch、あとはエミュレーターのみが対象で、私が使っているMoto360やSamsung Gear Liveはまだ対応していないそうです。
今までAndroid Wearのバージョンアップはメーカーによらず即座に行われていたので、これが切り捨ての始まりなのかちょっと心配です。
さすがに、両端末とも登場後2年近く経っているのでそろそろ買い替え時期でしょうか。

それにしても2.0は随分デザインが洗練されましたね。
通知カードはAndroid Wearが登場した当時の2年前の時点で古臭く感じていたので今回の変更点は随分好印象です。



Android high-performance audio

Androidではパフォーマンスの高いオーディオアプリを作るのは困難だけれど、ハードウェアをきちんと選びつつコーディングをしっかり行えばDTMクオリティのオーディオアプリが作れるという話。
コードを例に観客にどのコードが悪いのかを問いかけるスタイルで、一人の観客がバシバシ答えていくという愉快な状況に。
言い換えるとハイパフォーマンスオーディオの解決策が存在していながら伝わっていないことを表しているといえます。
難しい話ではなく、すぐに始められる話がメインなのでオーディオアプリを作る人は必見。


Android Auto

今年もAndroid Autoのブースが出来ていました。去年の話では去年中にAndroid Auto対応車が日本でも出ると言っていたのに未だに出てこないので質問してきました。
音声認識の精度が中々上がらずに製品レベルに達しておらず、調整中とのこと。

Autoの新技術である無線部分についてはやはり仕組みとしては映像を送り続けているだけらしく、実装レベルもまだ研究段階ですぐに対応できる話ではないとのこと。

ということでトータル的に見てもこのままではAndroid Autoは短命に終わりそうな感じです。


本命のAndroid in Carについても今後すぐに発売されるものではないようです。
スマートフォンをプロセッサーにして自動車側をシンプルにするAndroid Autoの発想は製品ライフサイクルからいうと適切に思えるのですが、車載コンピューターのパワーがスマートフォンを大きく上回るようになり、かつスマートフォンの進化が停滞している現状でどちらが正解になるでしょうか。


なぜか会場の中央で皆がフラフープを始めていました。
私もフラフープを体験したのですが久しぶりに回すと中々回せないですね。
それにしてもこの外聞を気にせず遊びまわる感じはまるでヒッピーのようで改めてGoogleって西海岸の会社だなぁと実感。


APAC Dinner

本日の夕方はAPAC(アジア太平洋)のGDGコミュニティーによるパーティです。
写真をのせることが出来ないのですが、アジア人同士で食事を楽しみながらゲームをや話し合ったりしました。
当然言語は英語なのですが、アジア人同士だと英語が聞きやすくなるのが不思議。やはりアジア人特有の発音とかが有るんでしょうか?

ところで様々な国の人から「Love Letter」という1995年の邦画について知っているか?と聞かれました。
「お元気ですか?」というセリフが特徴的らしくて、お元気ですか? お元気ですか?って言われました。
日本でそれをやるとプロレスラーのモノマネに思われるよ と言ったのですが伝わっていないようでした。

あと、インド映画はやたら推奨されました。

After Party

After Partyに参加するために、I/O会場に戻ります。


同時に日が沈んでかなり寒くなってきました。昨日と比べてかなり温度が下がっているようです。
暖かくなるにはお酒を飲んで踊るしか無い!?


ただでさえ華やかな印象がある今年のI/O会場がAfter Partyで色とりどりに電飾され更に派手になっていました。
照明が原色ばかりで異様な雰囲気に


昨日のAfter Concertがアンフィシアターを中心としていたのに対してAfter Partyは会場全体がパーティー会場になっていて、今日のほうが規模が上。

そして会場のあちこちで展示が行われています。
やたら3Dっぽい恐竜とか


ライトアップされた草とか


休憩部屋


なぜか随分とひっそりとした場所に展示されているゲームセンターコンソール。


ライブも行われていました。


オーディオ周りはWeb Audioで行っているようで、PCはChromeBook Pixelの第二世代が使用されていました。


踊っているというかトランスっているというか


やたらデカイワーゲンバスも電飾されて派手派手、LEDが7色に輝いています。


車内に入れるようになってました。
ワーゲンバスなのに2階建て


運転席に入りました。
謎のメーター類。

ハンドルは水平に寝てました。タイヤとの位置関係を考えるとこうなりますよね。


I/Oロゴマークもライトアップされていました。
食事も美味しいしお酒も充実していていい感じです。I/O3日とも食事のクオリティが上がってくれると良いのですが



結局最後のバスでホテルに帰りました。
帰りのホテルでレンズフードがなくなっていることに気づきました。
もともとI/Oに行く直前に開封したくらい使っていなかったのですが、どこに置いてきたことやら



Google I/O 2016渡航記 I/O 3日目編

$
0
0
今日はついにI/O最終日です。
始まるときには、これから3日もあるなんてどれだけたっぷりなんだろうと思ったけれど、3日目になってみるとあっというまですね

今日はATAPの発表があるので、またしても朝一で並ぼうと思います。
ATAPは元Motorolaの先進技術研究部隊でARAやSoliといったすぐ実用になるかどうかわからないけれど技術的に面白い発表をいろいろとしてきているのでとても楽しみです。

それにしても、連日早朝起きは流石に辛いですね

ATAPのセッションは10時からなので最初の1時間は完全に空き時間。
早めにたどり着いて並んでおきます。

朝食を取ってすぐに並びに行きます。
今日もドーナツとベーグル。ベーグルにチーズがとても美味しいです。
流石に並んでいる人はそんなにおらず列の前の方に並ぶことが出来ました。


ATAPのセッションでは新しい発表はなく去年行われた発表の成果報告という感じ。

TrustAPI

AbacusはTrustAPIになりまもなく実用段階になるとのこと。
Androidでは顔認証や指紋認証、Bluetooth認証など様々な認証がありますが、これらを複合的に使用することでパスワードを使わずに認証をリアルタイムに行う仕組みです。
バッテリーへの負荷など含めてどの程度使い物になるのか試してみたいです。

JACQUARD

服にタッチセンサーを組み込むJACQUARDはカフス風のパーツにコンピュータを仕込むことで防水を保ったままより服っぽくなっています。
服に組み込んだ場合、毎日着るというわけでもないし季節によって利用形態も変わってくるので本格的に普及する気はしませんが、面白そうな技術では有ります。
今年中にリーバイスと組んで発売すると言っていますが、果たして本当に発売されるのか?価格はどれくらいか?発売される国はどれくらいか?気になるところです。

Project Soli

ATAPの中でも最も先進的で面白そうなのがProject Soli
センサーを使うことで直接手を触れずにデバイスを操作できるという仕組みで、去年のセッションでもサイズの小型化がアナウンスされていましたが、今年はさらに小型化されウェアラブル内に組み込まれていました。
発熱やバッテリー持ちを考えるとまだウェアラブルに内蔵して実用できるレベルではないと思いますが、本当に実用レベルになればウェアラブルでの操作性が大幅に改善しそうです。

ARA

スマートフォンの部品を取り外し可能なARAについては、開発続いていたのか、という状態。
CPUなどの取り外しができなくなり代わりに音声での取り外しに対応しました・・・
が、正直音声で部品を取り外したいと思う時がいつあるのやら
単に完成を急ぐために規模を縮小してそれをごまかすためにおまけ機能をつけたのかな?という印象。

VR

VRについてはコンテンツの誘導方法についてコンテンツ作成環境の紹介がされていました。
実際に体験してみましたが、特定の方向を見たくなる技術と、特定の方向を見ないと物語が進まない仕組みの組み合わせでVR問題である特定の方向を見せたい問題をうまく解決しているように感じました。

全体的に夢の技術発表だった去年のATAPに対してことしはそれらが実際に使えるようになりますよって紹介だった気がします。
そういう意味ではATAPという枠からは外れつつあるのかもしれません。

Google本社

その後、他の参加者やGooglerと話をしばらくしていたのですが、Google本社に行くことになりました
駐車場にGoogle自転車が置いてあったので借りていくことになりました。


Google自転車一見するとただのママチャリなんですが、ブレーキが特殊です。
一般的な自転車は右レバーが前輪ブレーキ、左レバーが後輪ブレーキだと思うのですがこの自転車は
左レバーが前輪のブレーキになっていて、右レバーはありません。
では、後輪のブレーキはどうするかというと、ペダルを逆向きに回転させます。
ペダルを数センチ逆回転させると後輪にブレーキがかかり始めてその後は圧力に応じてブレーキの効き具合が変わります。

最初は若干違和感があったのですが、踏み込む力によってブレーキがかかっていく感覚はちょうどバイクのブレーキと同じなので意外とすんなり使うことができました。
後ろからついてきた人がいうには、ブレーキを踏み込むときに足が動くので後ろから減速しようとするのがわかって楽だったとのこと。

Google本社内は、色々なオブジェクトが有るのですが、恐竜を鳥が食べているという進化論を暗喩するようなオブジェクトから鳥が排除されていました。
現在の恐竜オブジェ。普通にかっこいい。

以前の恐竜オブジェ、鬱蒼とした木々の中に突縁現れるテラノサウルスの骨とよく見るとそれが鳥に食いつくされた後というグロテスクなオブジェは哲学的だったけれど怖さもあった。


本社内には小学生の職場見学のようなイベントが行われていたりして、以前に比べて一般人が増えているように思います。
その辺りを含めて不気味なオブジェは控えたのかもしれません。

Google本社は最近構成変更が行われてビジター用のスペースが確保されGoogleの歴史を知ったりGoogleグッズを買ったりする場所、ドロイド君の置物が置かれている場所などが本社の端の方に統合され広い社内を歩きまわらずに見て回ることが出来るようになりました。(おそらくにおいてはGoogle側としてもビジターがあちこち歩きまわってほしくないという意図もあるのかと思います)
Google本社の敷地はゲートなどがなく建物の外であれば誰でも入ることが出来る状態になっていて、しかも、Google社員はけっこう建物の外でプチミーティングをしていたりするのでこういう対策が必要になったのかと思います。

Google本社ではおみやげを幾つか購入しました。
幾つかは子供のために、幾つかはイベント関係でお世話になった人のために、幾つかは自分のために買って帰ります。

それにしても、Googleグッズ、かなり種類が減っていた気がします。
単にI/O期間中で買い占められた後だからかもしれませんが、ここで一気に色々買おうと思っていたので買いづらくて残念。

その後I/O会場に戻るとクロージングの準備が進んでいました。

去年までですと、クロージング間際になると会場がかなり閉鎖されて再入場できなくなっていたのですが今年はそんなこと無く普通に入っていくことができました。
このあたりも田舎でやるメリットかも。

会場ではもうセッションも残っていませんでしたが、Android4.0のコードネームとして知られるICSことアイスクリームサンドイッチが配られていました。
クッキーとアイスクリームの組み合わせを指定することができます。

これが驚きの旨さ。
クッキーはその場で温めた物で、それでアイスクリームを挟むので外はアツアツカリカリのクッキー、中は冷たくとろとろなアイスクリームという不思議な味。
その構造的に出来た瞬間から溶け始めるのでその辺解けたアイスクリームだらけになっていましたがとても美味しい。
作るにも売るにも食べるにも大変そうなので、日本で売るのは難しそうだけれどこれは病みつきになりそう。

その後はBestbuyに行くことにしました。
狙いはHuaweiWatchとAmazonEchoです。
Mountain ViewのBestbuyは歩いて30分ほどっぽいけれど、現地の人たちからは車で行くことを強くおすすめされたので、
本田さんがLyftで車を呼んで待つ・・・ が来ない。
散々待った挙句しばらくしたらドライバーらしき人が来てお前たちが呼んだのか? ずっと待っていたという。

??? となりながらも 車に案内され、Lyftのナンバーと照合して乗り込んだら、どこへ行くのか? と聞かれる。
Lyftを使ったこと有る人ならわかると思うけれど、Lyftは出発地点と到着地点をアプリ上から指定する仕組みでタクシーの運転手は本来事前にどこへ行くかわかるはず、この時点で不信感満点だったのだけれど、MountainViewのBestbuyだというと凄い不機嫌な顔をして、イベントで渋滞しているここまで来るのに30分もかかった。駐車場を出るのに1時間はかかる。 俺なら歩くね。降りて歩けと まさかの乗車拒否。
どうも新人の運転手なのかアプリの使い方を分かっていなかった模様。
結局降りて歩くことに。

と思ったらここで運転手が来て無課金にしてやるから☆5の評価をつけろ(Lyftは降りるときにドライバーの評価をつける仕組み。評価が悪いと運転手の仕事がなくなるため運転手にとって高い評価を維持し続けることが大事)とすごんできた。
☆5をつけたら運転手はすぐに車に戻ってイライラした様子ですごい勢いで駐車場を走り去っていった。

その後課金されたメールが・・・
今までUberやLyftを使っていてここまで不愉快な気持ちになったことはなかったけれど、こんな運転手もいるのかと驚き。
(あとから本田さんがLyftにクレームを入れたところ全額キャッシュバック+クーポンを受け取ったとのこと)

さて、仕方ないのでBestbuyまで歩くことにします。
Lyftで他の車を探そうにも真っ先に先ほどのドライバーがヒットしてしまいます。
流石にもう会いたくないのでてくてく歩く。

サンフランシスコと違って治安が悪い感じはしないけれど、とにかく人がいない。
もしここで襲われたり何かあったらどうしようと思いながらてくてく歩いていくとやっとBestbuyを発見。


Bestbuyまでつくと、先着していたほかのI/O参加者からEcho 売り切れたよ、との衝撃の言葉が・・・
店内を見るとEchoもHuaweiWatchも(というよりAndroidWearの殆どが)売り切れ状態。
I/O参加者の多くがここで買い漁っていったのでしょう。ここまで歩いてきたのは一体何だったのか・・・

しかたがないので(日本でも買えるようになりましたが)おみやげにMissfit Flashだけ買って退散。

夕食はBestbuyのすぐ近くにあったIN-N-OUT burgerへ
店内はびっくりするほどノイジー
皆が大声で叫ぶように話していて、アメリカはうるさいところが多いと思っていたけれどこれまでで一番うるさい。
店員と会話が全然できず、商品をジェスチャーで伝えてようやく買うことが出来ました。(一緒にいった人はなぜかバーガーのセットを頼んだのにハンバーガーが2つ入っていました)
値段はアメリカの物価を考えるとかなり安く、それでいてボリューミー。
ドリンクも飲み放題で言うことなし。味はバーガーキングほど本格的ではないけれど、マクドナルドとかよりは一段上の感じ。


なんだか色々あったけれど、このハンバーガーで全て救われた気がします。
あとはホテルに帰って今年のI/Oはおしまい。
明日はMakerFaireに行って明後日は帰国するのみです。

今回のI/O、かなり賛否両論だった気がしますが、賛が多かったように思います。
否定的な意見で言うと、暑かった(これは事実だと思うけれど、個人的に湿度の少ないカラッとした暑さは心地よくて苦に感じなかった。これが辛い人にとってはきつかっただろうというのはわかる)
セッションのオペレーションが悪かった(これについては完全同意、行列が無秩序に並んでいるのでセッションの入り口から行列を逆に追いかけていかないと何の列かもわからない。セッション入れ替え時に中の人が一回でないといけないのか残って良いのかも統一されていなかった。セッションのキャパシティはもう少し大きくて良いのでは)
おみやげがなかった(おみやげが無くなること自体は好意的に受け取っているけれど、だったら事前に告知して欲しかったと思う。転売ヤーに一泡吹かせることは出来たかもしれないがほんとうに行きたい人にチケットが回らない問題は今回は解決できなかった)
良かった点としては、発表の内容が幅広く、かつ開発者に関係がある話が多かった。
開放的な空間のおかげで例年ほど息苦しくなかった。(特にアフターパーティーの雰囲気は最高だった)
会場付近の渋滞なども少なく、会場に由来するぐだぐだは発生しなかった(セッションがダメなのは例年通り)

ということで、行くまではかなり不安だったけれど終わってみると2012年以来に楽しめたというのが率直な感想。
そして、開発者としてやれることがかなり増えたのを感じたくさんの宿題を貰った気がします。

Google I/O 2016渡航記MakerFaire編

$
0
0
今日はMakerFaire bay Areaに行きます。
MakerFaireの会場はサンマテオというサンフランシスコ空港付近にあるため、最終日のホテルは空港付近のホテルに取りました。
Uberで車を呼んで最終日のホテル、Crowne Plaza San Francisco Airportへ行きます。

このホテルを選んだ理由は
CalTrainの沿線のためSan Jose方面からのアクセスが良い(結局Uberで移動したけれど当初はCalTrainという選択肢もあった)
同じ理由でMakerFaire会場までのアクセスも比較的良い
空港までのシャトルバスが有り翌日空港までのアクセスも良い。

来たのは女性のドライバー 。
昨日のLyftはなんだったのかと思うほど親切な対応で、3つのスーツケースを試行錯誤しながらトランクに押し込んでくれました。

車に乗っていたら何と雨が降り出してきました。
それもけっこうな勢い。もしこのレベルの雨がI/O期間中に振り出していたら阿鼻叫喚になっていた気がします。

その雨もホテルに付いた時にはやみ、ホテルに荷物を預けてCalTrainの駅へ向かいます。
移動距離は42.9km日本だと中々この距離をタクシーで行こうとは思えない距離ですが、料金はわずか29.94ドル
しかも、プロモーションコードがあったため20ドル割引きされて9.94ドル。これを同乗者3人で割ったため一人3ドル程度、驚くべきコストパフォーマンス。

気になった人はコチラから申し込んでみてくださいプロモーションコードをゲットできます。
しかも、だれかがプロモーションコードをゲットすると私にもプロモーションコードが与えられるという俺得システムになっているようです。うっしっし

CalTrainの駅まではハイウェイを超えないといけないのですが、きちんと遊歩道が整備されていて歩きやすくなっていました。


橋の上から高速道路を見下ろす。
日本と違ってアメリカの高速道路は無料ですが、それにしても道路の痛みぶりがすごい。
中央分離帯の間もゴミだらけ
道路幅は4車線もあってかなり豊富に取られているのに夕方頃はこの道でも大渋滞します。

高速道路を超えるとポルシェやアキュラといった高級車ディーラーが並ぶちょいセレブな雰囲気の街がありました。


ディーラーを超えるとCalTrainの線路が見えてきました。
地図で感じていた印象よりずっと近い。


それにしてもこの踏切かなり動きが雑です。
列車が来ていないのに遮断機が降りて何も通りすぎずに遮断機が開いたり、逆に列車来ているのに遮断機降りず、列車が警笛を鳴らし続けて踏切を突破したり・・・

踏切を渡ると駅が見えてきました。
日本の駅と比べると随分と質素です。
アメリカというと豊かな国、先進的な国という印象があったのですが、豊かさってなんだろうとふと疑問に思いました。



駅は完全無人。Clipperをかざす機械だけが有りました。Clipperをかざすと入場記録になり、降りるときにかざすと退場記録となって料金が精算される仕組み。
ただ、日本と違って改札などがないのでかざすこと無く乗車できます。
車内で検札が来た時に入場記録があるClipperかチケットがないとアウトで罰金。
これって、他所から来た人にとっては凄い不親切で分かりにくいと思う。今回はClipperを買っていたから良かったけれど、Clipperを持っていない人向けのチケット販売所は結局見つけられなかった。

サンフランシスコ行き(逆方向)のCalTrainがやってきました。
CalTrainは機関車が全てサンノゼ側を向いているのでサンフランシスコ行きは機関車が後ろから押す形になるのですが、車体をぶった切って無理やり運転台をつけた姿は中々の迫力


今度こそ目的のサンノゼ方面行が来ました。
サンノゼ方面側はちゃんとした機関車が引っ張る形です。
CalTrainって凄く巨大だし、スチールむき出しッて感じのデザインでいかにもアメリカンなのですが何と日本車両製で社内には日本車両のロゴマークも有ります。

ブロードウェイステーションから会場があるサンマテオ駅までは2駅ですが、検札が来ました。
ズルしなくてよかった というかClipper買っておいてよかったー

サンマテオの駅につきましたが・・・
看板が倒れてベコベコなままになっています。
偶然最近倒れたのかもしれないけれど、アメリカにいるとこういうのをよく見かけます。

ただ、個人が持っている消費は大きいようで車は高い車がよく走っているように思います。
ということでサンマテオの駅から歩いて15分ほどでMakerFaireの会場につきました。
MakerFaire BayAreaに来るのは2度めですが迷わないか内心ドキドキでした。


あと、途中はずっと住宅街の中を歩き続けるので日を遮るものがほとんどありません。
湿度が低い中ガンガン照りつけるので帽子を持っておけばよかったです。
会場でチケットを見せます。

MakerFaireのチケットはオンラインで購入できるEventbriteというサービス。
日本で言うところのATNDのようなものですが、IntelPartyでも使われていたり、去年ではGoogleI/O自体もEventbriteで登録するようになっていました。
サービスのクオリティが高いですし、いろんなイベントに参加するときにこうやって一つのサービスにまとまっているのは管理が楽で嬉しいです。


それではMakerFaire BayArea2016で見かけたものを色々と順不同で

MakerFaireでみたもの

廃材で作った馬。
日本でも民芸品とかでよく見るようになりました。


鉄のタコ
こういう、巨大なアート品が多いのもMakerFaire bay Areaの特徴な気がします。

Googleは工作時に便利な防護メガネを無料で配っていました。
普通のメガネと違って左右の空きが小さく物が飛んで目に刺さったりしないようになっています。
助かりますね。

ドローンレースもやっていました。
ドローンレースやってみたいですが、見る側としてはドローンが小さい上に高速なので視認性が悪くて観戦しづらかったです。
プロジェクトマッピングで床にチームロゴを表示するとかそういう工夫がほしい。

今回カメラはα7sにsel50f18f一本で行ったのですが、肉眼でもつらい光量でもISO8000まで上げる事で1/800までシャッター速度を上げてドローンが撮影出来ました。

旧車をEVに仕立てあげるのって3年前のMakerFaireでも見たのですが面白いですよね

EV NAロードスターは今年も出品。
マツダのロードスターが世界的に見ても名車と言われているのは有名ですが、実際のところユーノス(NA)ロードスターが圧倒的人気でそれ以降はそれほどでもないという印象を受けます。
少なくともアメリカではNAはソコソコ見かけますがNCは殆ど見ません。
それに対してボクスターが目立ちます。
原点回帰を図ったNDで再度人気が戻ると良いのですが。

ソーラーカー。この割り切りが凄い

新旧混在で言うとパワーグローブ(ファミリーコンピューターの周辺機器)でドローンを操るというのもありました。
もっとも操れずに墜落してドローンは壊れてしまいましたけれど。

中身はどんがらで作りなおしているっぽい

Makerと言えるかどうか微妙ですがハーゲンダッツを配っていました。
日本で言うと高級アイスの印象が強いハーゲンダッツが大量にゴロゴロ配られていくのは見ていて圧巻。
試作品が並ぶ中にあって大量の食料品を安定供給する力をMakerたちに見せつけているかのようです。


屋外展示らしくBBQの屋台もでていました(有料)
アメリカの食事というと美味しくない印象が強いけれどBBQはアメリカ凄いと思う。

ARDUINOベースのゲーム機

ホットケーキプリンター
コスプレに似合わないPCを使っています。



3Dプリンター編み機
PCで入力したように編みこんでくれる機織り機ですが、これは3Dプリンターと言って良いのだろうか・・・

暗闇エリアは前回に比べて大物が減った気がしますが光や影を使った演出が楽しかったです。
光る牛

磁気で浮かぶ物体
ゆっくりと回転していて影の移り変わりが楽しい。


その他様々な展示がありました。

再び屋外に出て
体中にスピーカーを付けて踊るロボット
なんともいえないゆるさが素敵です。


あと燃やす系の展示が多いのもアメリカっぽい
ほとんど脈絡なく火炎放射が行われていたりしますが、その中でも面白かったのが謎のリズムゲー
リズム通りに操作すると(この操作するパーツの作りがすごく雑で操作性がひどく悪い)炎が出るというもの。
単純すぎるリズムとあいまって耳に残りました。

MakerFaireの会場は本当に広かったです。
3年前に行った時も広いと思っていたのですが、あのときは店番があったりであまり見て回ることが出来なかったけれど、今回一通り回ってほんと広さを実感。
ただ、正直なところ3年前とかぶる展示が多かったという印象。出展者が固定化してきているんでしょうね。

純粋な見学者としていくなら一度行けば十分二度行く必要はないかなぁ

さてそんな感じでホテルに戻ります。
と思ったら帰りにGoogleの社員さんに会いました。この方は今はMountain View勤務ですがもとは日本勤務ですごくお世話になった人。
以前は雲の人という印象だったのですが、今回は色んな話ができて嬉しかったです。
やっぱりベイエリアは人に会いに行き、ものを見せに行く場所だとつくづく実感。

帰りのCalTrainでも検札が回ってきました。
前回は全く検札が来てなかったのでけっこうズルする人が多いんじゃないかと思っていたのですが、前回はたまたまだったのかもしれないです。
あと今更気づいたのですがブロードウェイ駅は土日しか止まらないらしいです。
今回たまたま土曜日だったから良かったけれどホントラッキー、アメリカの交通機関は土日にダイヤが大きく変わる傾向があるので要注意ですね。

CalTrainを降りたら夕日が美しかったです。

食事は移動が面倒だったのでホテルで食事。

しかし、ホテルだから割高なのは当然ながらさすがアメリカ。ホテルの料理も大味で大量です。
味以前に満腹になることを再優先するメニュー構成はさすがの一言

アメリカといえば毎回戸惑うのがホテルのシャワー。
一体何かのコンテストなのか?ッて思うくらい操作方法が統一されておらずエキセントリックです。
蛇口を倒したり押したり・・・
今回もまたクセモノでした。
見た感じひねるっぽいデザインですが、ひねっても反応無し。
こんなことでへこたれません。どうせ傾けたりするんでしょ。と思ったけれど傾きもせず。
じゃぁ、押したら・・・ 反応せず
引いたら・・・ あ、引けた けれど反応せず。
で、結局はこの引いた状態で左右にひねると水やお湯が出るという仕組み。
ひねるだけでもダメ、引っ張るだけでもダメ。
どちらも同時にやった時だけがお湯が出てきます。
しかもレスポンスが悪くひねった後しばらく立ってからお湯が出てきます。
初見殺しすぎる

さて、長かった旅もいよいよおしまい。
明日はSFO経由で帰国するだけです。

無料でGoogleサーバーにHTTPSのサイトを公開する方法

$
0
0
ちょっとしたWebサイトをサーバーを用意せずに立ち上げたいという時があります。
イベントを告知するサイトであったり開発中のサイトをスマートフォンから見たい時とか、サーバーを新たに用意するのは面倒だなぁと感じる時、Firebaseを使うと便利にサイトを公開することが出来ます。
httpsに無料で対応するのでProgressive WebApps対応サイトも作れちゃいます。
2016年9月3日時点では1 GBまでのファイル容量に対応し10 GBダウンロードされるまで無料です。
ここでは静的なHTMLをFirebaseで公開してhttpsでアクセスするまでの方法を紹介します。

必要なもの

Firebaseを使うにはGoogleアカウントが必要です。
Mac(おそらくLinuxやWindowsでも出来ると思いますが今回は説明を割愛します。)

Node.jsのインストール

Node.jsにアクセスして
v4.5.0 LTSをダウンロード

nhode-v4.5.0.pkgをダブルクリックしてインストールを継続
途中管理者権限のパスワードを聞かれるので入力する。

Firebaseのインストール

ターミナルを開いて以下を実行
$ sudo npm install -g firebase-tools


Firebaseのプロジェクトを作成する

Webブラウザを開いてFirebaseのサイトを開いてSee our web new site をクリック


GET STARTED FOR FREEをクリック


新規プロジェクトを作成をクリック

プロジェクト名に任意の名前を入れて
国/地域に日本を選択して「プロジェクトを作成」をクリック


作業フォルダの作成

静的なファイルを配置するための作業フォルダを作ります。
今回はドキュメントにfirebase/demoというフォルダを作成してみます。
ターミナルに戻り次のコマンド実行する。
$ mkdir -p ~/Documents/firebase/demo
$ cd ~/Documents/firebase/demo


Firebaseにログインする

Firebase toolはブラウザとアカウント情報を連携することが出来ます。
ターミナルで以下のコマンドを実行します
firebase login

ブラウザが立ち上がってアカウント情報が求められた場合は先ほどFirebaseのプロジェクトを作ったGoogleアカウントでログインしアカウント連携を許可する。

ローカルの初期設定を行う

ターミナルに戻り
firebase init

What Firebase CLI features do you want to setup for this folder?
と表示されたらデータベースの設定を行うかサイトの設定を行うかを選択できる。初期状態ではどちらも設定される状態なのでスペースキーをおしてDatabase: Deploy Firebase Realtime Database Rulesにチェックが入っておらずHosting: Configure and deploy Firebase Hosting sitesにチェックが入っている状態とする。


What Firebase project do you want to associate as default?
が表示されたら先ほどブラウザで作成したFirebaseのプロジェクトを選択してEnterを入力する。

What do you want to use as your public directory?と表示されたら(public)となっているのを確認してEnter。
Configure as a single-page appと表示されたらNと入力してEnter。

Firebase initialization complete!
と表示されたら準備完了。

書類フォルダに作ったfirebase/demoフォルダを開くと中には
firebase.json(firebaseに関する情報が入っている)
npm-debug.log
とpublicフォルダが入っています。
publicフォルダ内に入っているファイルがWebホスティングされて公開されます。

サイトを公開する

ページを公開したい時や新しい内容に変えたい時にはターミナルで書類フォルダのfirebase/demoフォルダにいることを確認して
$ cd ~/Documents/firebase/demo

次のコマンドを実行します。
$ firebase deploy

もし、次のエラーが表示されたらログイン状態が外れているので
Error: Command requires authentication, please run firebase login
次のコマンドを実行して再度Firebaseにログインしてからfirebase deployを行ってください
$ firebase login


デプロイに成功すると
Hosting Site:の後にサイトのアドレスが表示されるので、そこにアクセスしてみましょう。
無事にindex.htmlが表示されたら成功です。


HTTPSサイトというとGithub Pagesを使うことも出来ます。そちらについては他にまとめている人がいるのでぜひそちらも参考にしてみてください。
http://liginc.co.jp/web/html-css/html/96453

HackerTackle16 開催

$
0
0
今年もHackerTackleのイベント運営を手伝わせてもらいました。
このイベント、HackerTackle(博多来る?)というダジャレになっていて、福岡では珍しい純粋な技術者向けトークイベントです。
イベントについては、対象者をコードを書いている人に限定しプログラマーが知っておいたほうがいい内容かどうかというのが登壇の条件になっています。「プログラマーも知っておいたほうがいい内容は対象外」

そのうえで運営が聞きたい話を決めて、それについて詳しい人を呼ぶというスタイル。
ジャンルとしては言語系(GoやSwift、Kotlinなど)やトレンド系(FinTech、深層学習、ProgressiveWebApplsなど)、インフラ系(Realm)等さまざま。
一方で有りがちなUXデザインなどは対象外となっています。
また、あまり新しくない話(C言語とか)については知りたい人は学んでいると思うということでこれもまた除外。

そんなガッツリ裾野が狭い方針というのもあって集客は前回も今回も苦労しているのですが、それでも今回は80人を越す参加者がいました。
しかも、事前登録していただいた人が全員参加、ドタキャンゼロ。

スポンサーを募集せずイベント運営費は参加費用で賄うという方針だったため、有料イベントで登壇者の方には謝礼なども出来ず中には旅費を負担していただいてまで来ていたけていたりと本当にありがたい限りです。

セッションの様子を幾つか紹介します。
Java9について話しているきしださん。 まさかり振り回しまくりでした。


深層学習と機械学習について仕組みや事例を紹介している佐藤さん。
豊富でリアルタイムに学習が進む様子や、音声認識のデモなどライブデモが豊富でした。


Goについて語る横山さん。
いまやバックエンドでは一つの勢力を築いているGoですが当初はかなり懐疑的な目で見られていました、横山さんはその時からコツコツとGoを試されています。


Realmについての山崎さん
ですが、内容はBytecode weavingというバイトコードを書き換える技術について
Realmのパフォーマンスと利便性の両立もこういう土台を元に作られているんですね


ProgressiveWebAppsについて 田中洋一郎さん
私が最初にGoogleI/Oに行こうか迷っていた時に背中を押してくれたのが田中洋一郎さんのBlog
当時、I/Oでどんな発表があっているのかは知ることが出来ても参加者はどういう1日を過ごすのか?についてまとめているサイトは他になかったのでとにかくこのblogを何度も眺めて悩んだのを覚えています。(私がI/O渡航記を毎回書くようにしているのもこのBlogの影響です)
なので、イベントに参加してもらえることを知った時はすごく嬉しかったです。
ProgressiveWebAppsについてはFirespeedでも随時取り入れていく予定です。


このようなセッションが全18セッション、3トラックが並行で6時間ぶっ通しという濃いイベントになりました。

懇親会はハンバーガーやスナック菓子の立食形式。
この手のイベントで定番なピザより手に持ちやすく、食べながら喋りやすいのが嬉しい。
日頃話せない人とも話せて嬉しかったです。

2次会ではイカ食べたりしました。 美味しい。


さて、話だけ聞いて満足していたら意味が無いので早速いくつか行動に移そうと思います。

Android Wear2.0 Watch face Complicationsを作る 基礎編

$
0
0
Android Wear2.0 Watch face Complicationsを作る

はじめに

この記事はAndroid Wear2.0 Preview3を元にかかれています。実際のリリース版ではAPIの挙動が変わる可能性があります。
対象読者はAndroidスマートフォンアプリの経験者で端末にOSイメージの焼き込みを行ったことがある人です。

目次

基礎
DataSync

Watch face Complicationsとは

Android WearではWatch faceという文字盤アプリを開発することができ、好きなデザインや天気予報が表示される文字盤など多様な文字盤が多くリリースされています。
関連記事:Android WearのWatch faceを作る(概念編)
しかしながら、画面にデータを表示する処理はWatch faceを開発する開発者がデータを取得して表示するまで全てを作る必要があったため、Watch faceの開発者は負担が大きかった上に必ずしも好きなデザインのWatch faceに欲しいデータが表示されるとは限りませんでした。

Android Wear2.0で追加される予定のWatch face ComplicationsはWatch face上に別アプリのデータを表示するための仕組みです。
Watch faceとデータを表示したいアプリ(以降Data providerと記す)がComplicationsAPIにより協調的に動作することが出来るようになります。

これによりユーザーが選んだ任意のWatch faceでユーザーが選んだ任意のData providerのデータを表示することができるようになります。


また、複数のアプリが並んで表示されるNotificationと違いWatch face ComplicationsはWatch faceの特定の領域に一つのアプリのデータが常駐する形になるため、ユーザーにとってもいつも同じ場所に同じ情報が表示され、ひとめ見るだけの視認性アップを期待できます。

ホームスクリーンにデータを表示するのはAndroidスマートフォンのホームウィジェットに近いですね。
また、送信元と送信先がお互いを意識しない状態でデータをやり取りして協調動作する仕組みは暗黙的Intentに似ている感じがします。

Watch face Complicationsの仕組み

Watch faceがOSにデータの要求を行うとOSがData providerにデータの要求を行い、Data providerがOSが定めた形式のデータを送り、OSがWatch faceにデータを送りWatch faceがWatch face Complicationを描画するという仕組みになっています。
Complication APIの使い勝手はホームウィジェットに似ていますが、開発者視点で見るとその仕組みは若干異なります。
最大の特徴は描画処理をData providerが一切行わず、Watch faceが行う点です。Watch faceはデータをData providerからもらいながらも実際にどのように描画するかについては自由に行うことができます。
これによりWatch faceは不特定なアプリのデータを表示しながら世界観を保つことができます。

今回はData providerを使用して2.0に対応しているWatch faceにデータを表示するアプリを作ってみます。

Android Wear2.0 Preview3の使い方


Android Wear2.0 Preview3を使用するには以下の準備が必要です。
この工程では不安定なバージョンのOSを使用するため端末が起動しなくなるなどの不測の事態が発生する可能性があります。自己責任でご利用ください。

スマートフォンの準備

ベータ版Android Wearアプリ
Android Wear2.0 Preview3では新たにGoogle Play Storeにスマートウォッチから直接アクセスできるようになったため、スマートフォンアプリ側からアカウントデータを共有する機能がついた、ベータ版のスマートウォッチアプリを使用しなくてはいけなくなりました。

ベータ版を使用するにはまず、Android Wear developer preview開発者用のGoogleGroupsに参加します。

次にテスターへの申し込みを行います。
申請ページでテスターになるをクリックします。
数分から1時間ほどでベータ版のAndroid WearアプリがGoogle Playでダウンロードできるようになります。

スマートウォッチの準備

Wear2.0 Preview3を実機で試すにはプレビュー版のダウンロードサイトより、イメージをダウンロードしadbを使ってスマートウォッチに転送する必要があります。
現在のところ
lg watch urbane 2nd edition


Huawei Watch向けにイメージが用意されています。


Huawei WatchについてはAmazon.comが日本への発送も対応していて送料を含めても日本より安くなっています。

急ぎでないならこちらを使うという手もあります。

2.0の焼き方

Wearに2.0のイメージを焼きます。
イメージの焼き方については一般的なスマートフォンと同じ為省略します。

開発者プレビューを有効化

実機を使って開発を行う場合、イメージを焼いてスマートフォンとペアリングした後にWear側も開発者向けオプションを有効にする必要があります。

画面を上部から下に向かってスワイプしギアのアイコンをタップし設定画面を開きます。

システムー概要を開きビルド番号を7回タップします。

設定まで戻り、開発者向けオプションを選び、ADBデバッグを有効にします。
PCとWearがUSBで接続されている場合はWearにPCとのUSBデバッグを許可するかどうかを選ぶ画面が出てくるため「このパソコンからのUSBデバッグを常に許可する」を選択します。
Bluetooth経由でテストを行う方法についてはWatch faceを作る 5分で作るWatch faceを参照してください。

実機を使わない手軽な方法としてはエミュレータを使用するという方法もあります。
エミュレータの場合はWearを選びAPIレベル24を選択するとWear2.0となります。


新規プロジェクトの作成

それでは今回はランダムな値を表示するData providerを作ってみます。
Android Studioで新規プロジェクトを作ります。

Application nameなどは任意の値を設定

Android Target DevicesにPhone and TabletとWearを選び、Phone and Tabletのminimum SDKはAPI18以上、Wearは24以上を選択します。
今回はスマートフォン向けのアプリは作りませんが、次回以降で使用するためPhone and Tabletも選んでおきます。

Add an Activity to MobileではEmpty Activityを選択します。


Customize the ActivityはActivity NameにMainActivityを設定します。

Add an Activity to WearではAdd No Activityを選択してFinishを選択します。


2つのモジュールが生成されますが、今回はWearモジュールだけを作ります。

Complication Provider Serviceの作成

Data providerはComplicationProviderServiceを継承したクラスでデータの提供を行います。

モジュールWearにSampleComplicationProviderServiceクラスを作成しComplicationProviderServiceを継承します。
ComplicationProviderServiceクラスは抽象メソッドonComplicationUpdate()を持っているのでOverrideします。
SampleComplicationProviderService.java

public class SampleComplicationProviderService extends ComplicationProviderService {

@Override
public void onComplicationUpdate(int i, int i1, ComplicationManager complicationManager) {

}
}

このメソッドはWatch faceが新しいデータを要求しているときに呼ばれます。

引数名が意味を持たない名前のため何が渡ってくるかわかりにくいですが、第一引数には画面に表示するWatch face Complicationごとに振られたidが渡されます。
Watch faceによっては複数のComplicationを同時に表示することが出来るため、このidを使ってそれぞれのWatch face Complicationを区別して、たとえば世界中の時計を表示するData providerの場合、IDが1だった場合は日本、IDが2だった場合はサンフランシスコの時間を返すといったように区別して値を返すことができます。
第二引数にはどのような形式のデータ(後述)が求められているかが指定されるtypeが渡されます。
わかりやすくするために引数の名前を変更しておきましょう。
SampleComplicationProviderService.java

public class SampleComplicationProviderService extends ComplicationProviderService {

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {

}
}


データを返す

ここでは0〜99までのランダムな値を返すWatch face Complicationを作ってみます。
まずは0〜99の乱数を生成します。
SampleComplicationProviderService.java

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
int value = (int)(Math.random()*100);
}


次にデータのタイプを調べて値を返します。
どのようなデータタイプをサポートしているかはWatch faceにより変わるため、複数のデータタイプに対応することでより幅広いWatch faceで利用が可能になります。
Watch face側が対応しているTypeを提供できるWatch face Complicatinsのみが表示可能です。

データのタイプはComplicationDataクラス内にStaticな定数がTYPE_SHORT_TEXTというような名前で用意されているためそれを使って比較することができます。

データのタイプ


Typeの種類は次のようなものが有ります。
Typeごとに必ずデータを渡す必要がある必須項目と、データを渡してもいいし渡さなくても良い任意項目が決められています。

SHORT_TEXT

必須項目
Short text 短いテキスト(7文字以下)

任意項目
Icon アイコン
Short title タイトル(7文字以下)

用途
短いテキストに加えてアイコンやタイトルも表示できます。
アイコンは単色である必要があります。またWatch faceによって色塗りされることが有ります。
そのため、色に意味をもたせるのではなく、シンプルな図形で意味をもたせる必要があります。

ICON

必須項目
Icon

任意項目
なし

用途
アイコンのみを表示します。SHORT_TEXTと違ってテキストなどを表示できませんが、明確な内容の場合はこちらのほうが見やすいかもしれません。
アイコン画像にはVector画像を使うことができます。

RANGED_VALUE

必須項目
Value 値
Min value 最小値
Max value 最大値

任意項目
Icon アイコン
Short text 短いテキスト(7文字以下)
Short title 短いタイトル(7文字以下)

用途
ある程度の範囲のうちどの程度の割合なのかを示す事ができます。
たとえば電池の消費量や1日の目標運動量に対する現在値などで使用できます。

LONG_TEXT

必須項目
Long text 長いテキスト

任意項目
Long title 長いタイトル
Icon アイコン
Small image 小さな画像

用途
ちょっとした文章を表示したりするのに使えます。SNSの新着などを表示するのに便利そうです。

SMALL_IMAGE

必須項目
Small Image 小さな画像

任意項目
なし

用途
小さな写真を表示します。アイコンでも写真でもどちらでも可能。

LARGE_IMAGE

必須項目
Large Image 大きな画像

任意項目
なし

用途
Watch face全体を埋めるように表示することを想定しています。スライドショーを作成するなどに使用します。

必須の項目が入っていなかったり、逆に必須の項目にも任意の項目にも指定されていない項目の値を渡すと実行時例外になるため注意が必要です。

今回はSHORT_TEXTに対応したData providerを作るため、typeに渡される値がSHORT_TEXTのときだった場合のみ処理を行います。
SampleComplicationProviderService.java

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
int value = (int)(Math.random()*100);
if(type == TYPE_SHORT_TEXT){

}

}


データをセット

ComplicationDataクラスを作成してデータを詰めていきます。
ComplicationDataはComplicationData.Builderクラスを使って作ります。
テキストを渡すときはsetShortText()を呼びます。
引数の型はComplicationTextで、ComplicationText.plainText()を呼ぶことで生成することができます。
変数valueをComplicationDataクラスのインスタンスにセットするには次のようにします。
SampleComplicationProviderService.java

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
int value = (int)(Math.random()*100);
if(type == TYPE_SHORT_TEXT){
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(String.valueOf(value)))
.build();
}

}


complicationManagerのupdateComplicationData()を呼んで、引数にデータがセットされたcomplicationDataをcomplicationIdとともに渡します。
SampleComplicationProviderService.java

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
int value = (int)(Math.random()*100);
if(type == TYPE_SHORT_TEXT){
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(String.valueOf(value)))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}

}

コード全体だと次の通り
SampleComplicationProviderService.java

package org.firespeed.dataproviders;

import android.support.wearable.complications.ComplicationData;
import android.support.wearable.complications.ComplicationManager;
import android.support.wearable.complications.ComplicationProviderService;
import android.support.wearable.complications.ComplicationText;

import static android.support.wearable.complications.ComplicationData.TYPE_SHORT_TEXT;

/**
* Complication Watch face DataProviderがデータを提供するためのサービス
*/
public class SampleComplicationProviderService extends ComplicationProviderService {
/**
* データを返してほしいときに呼ばれる
*
* @param complicationId 画面上に置かれたWatch face Complicationごとに一意となるID
* @param type 表示するデータのType
* @param complicationManager ComplicationManager 結果を渡す
*/
@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
int value = (int) (Math.random() * 100);
if (type == TYPE_SHORT_TEXT) {
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(String.valueOf(value)))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}

}
}


Android Manifestの設定

Serviceの宣言

次にAndroidManifestにServiceをセットします。
AndroidManifest.xml

<service android:name=".SampleComplicationProviderService"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
</service>


Intent Filterの指定

システムがData providerに最新のデータを要求するためにACTION_COMPLICATION_UPDATE_REQUEST Intentを発行するので、ServiceにIntent Filterを設定してこれを取得します。
AndroidManifest.xml

<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/>
</intent-filter>


サポートするTypeの指定

サポートするタイプとしてSHORT_TEXTを指定します。
複数のタイプを指定するときはカンマでつなぎます。
AndroidManifest.xml

<meta-data android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="SHORT_TEXT"/>


データ更新間隔の指定

データの更新頻度を秒数で指定します。
秒数の感覚が短すぎるとバッテリーへの悪影響を及ぼすので可能な限り長い時間にすることが推奨されています。
一定間隔の更新を行わず、更新タイミングを都度プログラム上で指定する場合には0を指定します。

今回はテストのために1を指定しましょう。
AndroidManifest.xml

<meta-data android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" android:value="1"/>

AndroidManifest全体は次のようになります。
AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.firespeed.dataproviders">

<uses-feature android:name="android.hardware.type.watch" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.DeviceDefault">
<service android:name=".SampleComplicationProviderService"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/>
</intent-filter>
<meta-data android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="SHORT_TEXT"/>
<meta-data android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" android:value="1"/>
</service>
</application>
</manifest>


build.gradle

build.gradleはこんな感じ
app/build.gradle

apply plugin: 'com.android.application'

android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "org.firespeed.dataproviders"
minSdkVersion 24
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.support:wearable:2.0.0-alpha3'
compile 'com.google.android.gms:play-services-wearable:9.6.1'
}


実行する

Activity自動実行の無効化

今回はActivityが存在しないため、通常のRunを実行しようとするとエラーになります。
Run時にActivityを起動しないようにRun-EditConfigurationsを開きます。
Android appのwearを選び、Launch OptionsのLaunchでNothingを選びます。


APKインストール

実行モジュールがwearになっていることを確認し実行します。
対象端末をWear端末にしてAPKがインストールされるのを確認してください。

Activityがないため、インストールが終わってもアプリは自動実行されません。

Watch face Complicationsに対応しているWatch faceへの切り替え

最初にWatch face Complicationsに対応しているWatch faceを選択してWatch faceを追加する必要があります。
標準で用意されているWatch faceの中ではデジタルエレメントおよびアナログエレメントがWatch face Complicationsに対応しています。
スクリーンを右から左にフリックして、お気に入りに追加を選び

デジタルエレメントあるいはアナログエレメントを選択します。


ギアを選びWatch faceの設定画面を開きます。


LARGE IMAGE以外のWatch face Complicationsはデータで追加できます。


Watch face Complicationを表示する場所を選択します。


追加するWatch face Complicationを選択します。
今回作成したDataProvidersを選びます。


Watch face Complicationが追加されました。


Watch face Complicationsが追加されランダムな数字が表示されることが確認できます。
データの更新は1秒間隔としていましたが、実際には1秒毎に更新されることはなく2分ほどの間隔になります。
このようにWatch face Complicationはデータを提供するだけで実際にデータの更新要求を出すのはシステムで、実際の描画はWatch faceに依存することになります。


次回はスマートフォンと協調動作してスマートフォン側で指定した値をスマートフォン側のタイミングでデータを更新する仕組みを作ってみましょう。

参考サイト
Android Developers Watch face Complications

コードサンプル
https://github.com/kenz/ComplicationsDemo1

Android Wear2.0 Watch face Complicationsを作るDataSync編

$
0
0

前回はWear単独で動いてランダムな値を表示するだけのWatch face Complicationを作成しましたが、もちろんこれでは何の訳にもたちません。
そこで今回はより実践的なスマートフォン上で入力したデータをWatch face Complicationに表示する機能を追加してみます。
スマートフォン側の処理を作り変えると天気予報やツイート数など好きな情報をWatch face Complicationに表示できるようになります。

目次

基礎
DataSync

全体の流れ

スマートフォンのActivityからWearのWatch face complicationにデータを送るには次のような手順をふみます。
1.スマートフォンのActivityがWearにメッセージを送信。
2.WearのWearableListenerServiceがメッセージを受信。
3.WearableListenerServiceがシステムにWatch face Complicationの更新を要求。
4.システムがリクエストを元にProvider serviceにデータを要求。
5.ComplicationProviderServiceが最新のデータをcomplicationDataにつめてシステムに渡す
6.システムがWatch faceに最新のデータを渡す
7.Watch faceがWatch face Complicationを表示する


このうちData provider側で作成する必要があるのが1〜3と5、Watch face側で作成する必要があるのが7です。
それでは実際にデータの流れに沿ってプログラムを作っていきましょう。

メモ:Android Wear2.0 Preview3はその名の通りPreview版です。
挙動面に不安定な部分があり、正常にコーディングしていても正しくWatch faceが描画されなかったり、画面が反応しなくなることが有ります。
そのような時にはまずWearを再起動してみてください。

1.スマートフォンのActivityからWearにメッセージを送信


まずはスマートフォンのActivityを作っていきましょう。
NumberPickerの値が変更されるとWearに値をメッセージとして送信する処理を実装します。

build.gradleの編集

mobileモジュールのbuild.gradleを開いてください。

スマートフォン側でWearと連携するにはgms:play-services-wearableを使用します。
標準のテンプレートですでにwearableを含むcom.google.android.gms:play-services付与されています。このまま使用してもいいのですが、com.google.android.gms:play-servicesは多機能すぎてメソッド数が多すぎmulti-dexが必要だったりビルドに時間がかかりすぎたりするため今回はwearable以外の機能を使用しないようにします。
mobile/build.gradleのdependenciesにある

compile 'com.google.android.gms:play-services:9.6.1'



compile 'com.google.android.gms:play-services-wearable:9.6.1'

に変更します。

layout.xmlの編集

ここは実際のアプリではそのまま使うことはないと思うので、細かな説明は省略します。
単にNumberPickerを配置しているだけです。
layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.firespeed.dataproviders.MainActivity">

<NumberPicker
android:id="@+id/numberPicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</FrameLayout>



MainActivity.javaの編集

AndroidWearへのデータ送信を行う時にはGoogleApiClientを使用します。
GoogleApiClientを使ったデータの送信にはDataSyncとMessageという2つの方法があります。
DataSyncはそれぞれの端末内でデータを保持し、変更があった場合に互いに差分データを送りつけてお互いのデータを一致させるような仕組みです。
スマートフォンでもスマートウォッチでもどちらでも単独で動ける万歩計など、スマートフォンとスマートウォッチそれぞれが同一のデータを別々に更新する場合などに便利です。

それに対してMessageはデータを一方的に送りつけるイメージ。データの送信が行えないときはそのままエラーとなります。
構造がシンプルな分、実装も簡単になります。
また、Preview3の段階ではDataSyncは不定期にデータを受信しなくなる不具合が残っていてMessageのほうが安定しています。
今回はNumberPickerで選んだ値を一方的にスマートウォッチに送りたいためMessageを使用します。

Viewの取得とイベントハンドラの作成

onCreate()内でnumberPickerを取得して値変更時のリスナーを登録します。一般的な処理です。
MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NumberPicker numberPicker = (NumberPicker)findViewById(R.id.numberPicker);
numberPicker.setMaxValue(99);
numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {

}
});

}


GoogleApiClientの作成と接続、切断

インスタンス変数としてGoogleApiClientを宣言します。
MainActivity.java

private GoogleApiClient mGoogleApiClient;


onCreate()時にGoogleApiClientのインスタンスを生成します。
GoogleApiClientのインスタンスはGoogleApiClient.Builderを使用します。
MainActivity.java

mGoogleApiClient = new GoogleApiClient
.Builder(this)
.addApi(Wearable.API)
.build();


GoogleApiClientをonResume()時に接続し、
MainActivity.java

@Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
}



onPauseで切断します。
MainActivity.java

@Override
protected void onPause() {
super.onPause();
mGoogleApiClient.disconnect();
}


sendMessage()メソッドを作りメッセージの送信を実装していきます。
MainActivity.java

private void sendMessage(final int value){

}


Nodeの取得

データの通信を行うにはNodeを取得します。
Wearable.NodeApi.getConnectedNodes()を呼びNodeの一覧を取得します。
引数にGoogleApiClientを指定し、setResultCallback()を繋げてコールバックを設定することで非同期にノードを取得できます。
MainActivity.java

private void sendMessage(final int value) {
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(@NonNull NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
// ノードを取得

}
});

}


データの送信

データの送信はbyteの配列で通信を行う必要があるため、intをbyte配列に置き換えます。
MainActivity.java

byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();


取得した各ノード全てと通信を行うためにgetConnectedNodesResult.getNodes()の内容文forを回してWearable.MessageApi.sendMessage()を呼びます。
sendMessage()の引数は最初にGoogleApiClient、次にnodeのID、パス、送信するバイト配列、送信完了時の成否を受け取るコールバックをわたします。
データの通信は非同期で行われ通信が終わるとSendMessagerResultのonResult()が呼ばれます。

for (Node node : getConnectedNodesResult.getNodes()) {
Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), "/path", bytes)
.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
@Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
}
});

}


sendMessage()全体は次の通り
MainActivity.java

private void sendMessage(final int value) {
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(@NonNull NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
// ノードを取得
byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();
for (Node node : getConnectedNodesResult.getNodes()) {
Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), "/path", bytes)
.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
@Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
}
});

}
}
});

}

最後にonCreate()のnumberPickerにValueChangedListenerを設定し値が変更された時にsendMessage()を呼ぶようにしましょう。
MainActivity.java

numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
sendMessage(newVal);
}
});



MainActivity.java全体は次の通り

package org.firespeed.dataproviders;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.widget.NumberPicker;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;

import java.nio.ByteBuffer;

public class MainActivity extends AppCompatActivity {


private GoogleApiClient mGoogleApiClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NumberPicker numberPicker = (NumberPicker) findViewById(R.id.numberPicker);
numberPicker.setMaxValue(99);
numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
sendMessage(newVal);
}
});
mGoogleApiClient = new GoogleApiClient
.Builder(this)
.addApi(Wearable.API)
.build();
}

@Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
}

@Override
protected void onPause() {
super.onPause();
mGoogleApiClient.disconnect();
}

private void sendMessage(final int value) {
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
@Override
public void onResult(@NonNull NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
// ノードを取得
byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();
for (Node node : getConnectedNodesResult.getNodes()) {
Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), "/path", bytes)
.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
@Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
}
});

}
}
});

}
}


AndroidManifestの修正

AndroidManifestのApplication内にGooglePlayServicesのバージョンメタデータを追加します。
AndroidManifest.xml

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

2.WearのWearableListenerServiceがメッセージを受信。

送信されたデータをWearで受信する仕組みを作ります。
メッセージが飛んできた時に受信側ではIntentが飛ぶためIntentFilterでこれをキャッチしてServiceで処理を行います。

メモ:
MessageApiから送られてくるメッセージを受信するには送信側と同様にGoogleApiClientを繋いでWearable.DataApi.addListener()にリスナーをセットすることでも受け取ることが出来ますが、Wearのリソースは限りが有りComplicationProviderServiceのライフサイクルが短いことに注意が必要です。
Watch face ComplicationsにとってData providerはデータを提供するだけの役目で実際の描画はWatch faceが行っているため、データの提供が終わったData providerのServiceは役目を終えて自身のWatch face Complicationが表示されてある時であってもサービスが終了します。
そのためComplicationProviderServiceのonAtacch()やonCraeate()でGoogleApiClientを接続してもサービスが停止して切断されてしまいデータの更新を受け取ることは出来ません。
常時Serviceを起動しておくという方法もありますが、BackgroundのServiceはリソースが不足すると停止させられてしまうためこれも確実ではありません。
そのため、intentFilterを設定し、データの更新が起きたときだけServiceを起動し、速やかに値を保存、Watch faceのComplication更新を要求してServiceを終了します。

ReceiverService.javaの作成

Wearモジュールを開いて
WearableListenerServiceを継承したReceiverServiceクラスを作ります。
WearableListenerServiceはWearable.MessageApiで受信したデータを簡単に取り扱う仕組みでこれを継承することでMessageやDataSyncのイベントを簡単に受信できます。

ReceiverService.java

/**
* mobileからのメッセージを受信する
*/
public class ReceiverService extends WearableListenerService{
}

メッセージを受信したときはonMessageReceived()が呼ばれるためこのメソッドをOverrideしてメッセージ受信時の処理を記載します。
ReceiverService.java

@Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
}


送信されたデータはmessageEventのgetData()を呼ぶことで取得できます。
byteの配列で送られてきているのでこれをintに変換します。

int value = ByteBuffer.wrap(messageEvent.getData()).getInt();


Android manifestの修正

次にAndroid manifestにServiceを宣言しIntent filterを設定します。
pathPrefixにはWearable.MessageApi.sendMessage()で指定したパスを記入します。

AndroidManifest.xml

<service android:name=".ReceiverService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/path"
android:scheme="wear" />
</intent-filter>
</service>

メモ:以前のドキュメントなどでIntentFilterにBIND_LISTENEを指定するものが有りましたが、こちらのAPIは何か一つのデータを送るとすべてのサービスが呼び出されてしまう効率が悪くServiceが起動中に停止されるおそれがある作りとなっており現在では非推奨となっています。MESSAGE_RECEIVEDを使用してください。

これでスマートフォンで操作した値をWearに送り届けることが出来るようになります。
ここまでの処理に関してはWatch face Complicationsに限らず、Wearのアプリを作るのによく使われる一般的な手法となります。

3.WearableListenerServiceがシステムにWatch face Complicationの更新を要求。

これでWearはデータの変更を受信できるようになりましたが現在のままでは受信したデータは変数valueにセットされたままでなにも使われることがありません。
最新のデータが有ることをシステム側に通知してWatch faceにWatch face complicationを更新するように通知します。
データの更新をリクエストしても実際にデータを更新するまでの間タイムラグが発生することが有ります。
それまでの間Serviceを起動したままにするのは非効率なのでデータを保存してServiceを終了し、最新の値は最新データが要求された時に保存した値を読み込むことにします。

データの保存は好きな方法でいいです。今回はSharedPreferencesを使います。

SharedPreferences data = getSharedPreferences("pref", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = data.edit();
editor.putInt("value", value);
editor.apply();

更新を要求するにはProviderUpdateRequesterクラスのインスタンスを使います。
コンストラクターとして第一引数にContext,第二引数に更新するComplicationProviderServiceのComponentNameを指定します。
ComponentNameのインスタンスを取得するために、ComponentNameのコンストラクターを呼びます。
第一引数にContext,第二引数にるComplicationProviderServiceのクラスを渡します。
ProviderUpdateRequesterのインスタンスにrequestUpdateAll()を呼ぶことでデータの更新が要求されます。

new ProviderUpdateRequester(this, new ComponentName(this, SampleComplicationProviderService.class)).requestUpdateAll();


メモ requestUpdate()を呼び、complicationIdを引数に渡すことで特定のComplicationのみを更新することが出来ます。
古い非公式のドキュメントなどにおいて、全てのWatch face complicationsを更新したい時にrequestUpdateAll()を呼ぶのではなく、complicationIdを全て記憶しておき、繰り返しrequestUpdate()を呼ぶ方法が使われている場合があります。
これはAndroid Wear2.0 preview2のバグでrequestUpdateAll()が正常に動作しないことが有るという問題を回避するためのもので、preview3でこのバグは解決しrequestUpdateAll()が使用できるようになっています。
なお、requestUpdateAll()を指定しても更新されるのは指定したクラスWatch face Complicationsのみでその他のWatch face Complicationsは更新されません。

5.ComplicationProviderServiceが最新のデータをcomplicationDataにつめてシステムに渡す

データの更新をプログラム側で行うことになったのでAndroidManifestに設定していたandroid:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDSのandroid:valueを0に変更し定期的な更新をストップします。
wear/AndroidManifest.xml

<meta-data
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
android:value="0" />


SampleComplicationProviderService内で最新のデータを詰めてシステムに渡します。
最新のデータはSharedPreferencesに保存したので、変数valueに乱数を設定していた部分をSharedPreferencesから読み込むように修正します。

SampleComplicationProviderService.java

SharedPreferences data = getSharedPreferences("pref", Context.MODE_PRIVATE);
int value = data.getInt("value",0);



全体では次の通り
SampleComplicationProviderService.java

package org.firespeed.dataproviders;

import android.content.Context;
import android.content.SharedPreferences;
import android.support.wearable.complications.ComplicationData;
import android.support.wearable.complications.ComplicationManager;
import android.support.wearable.complications.ComplicationProviderService;
import android.support.wearable.complications.ComplicationText;

import static android.support.wearable.complications.ComplicationData.TYPE_SHORT_TEXT;

/**
* Complication Watch Face DataProviderがデータを提供するためのサービス
*/
public class SampleComplicationProviderService extends ComplicationProviderService {
/**
* データを返してほしいときに呼ばれる
*
* @param complicationId 画面上に置かれたWatch Face Complicationごとに一意となるID
* @param type 表示するデータのType
* @param complicationManager ComplicationManager 結果を渡す
*/
@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
SharedPreferences data = getSharedPreferences("pref", Context.MODE_PRIVATE);
int value = data.getInt("value",0);
if (type == TYPE_SHORT_TEXT) {
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(String.valueOf(value)))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}

}

}


これでスマートフォン側のActivityのNumberPickerを選ぶとWatch face complicationの値が置き換わるようになります。
置き換えのタイミング自体はWatch faceに依存するため、即時に変更されるとは限りません。
特に画面が薄暗くなるambientモードのときは画面更新間隔が1分間ごとになるのでData providerがデータを提供してから実際に反映されるまで時間差が有ることも見ることが出来ます。


次回は複数のWatch face complication typeへの対応や多解像度に対応したアイコンを作ってみましょう。



Android Wear2.0 Watch face Complicationsを作る 多データ型対応編

$
0
0
前回はスマートフォンからデータを取得してSHORT_TEXTを出力するData Provider を作成しました。
基礎編で紹介したとおり、Complicationsのデータ型にはいくつかのタイプがあります。
Data Providerは複数のデータタイプを提供することができ、一方でWatch Faceも複数のデータタイプをサポートできます。

目次

基礎
DataSync
多データ型対応

複数のデータタイプへ対応

Watch Face上にデータを表示できるようにするためには、Watch FaceとData Providerの両方が対応しているデータタイプが最低でも1種類以上ある必要があります。
そのため、Data Providerは可能な限り多様な種類のデータタイプをサポートすることで、より多くのWatch Faceに対応することができます。
今回は前回のSHORT_TEXTに加えてICONとRANGE_VALUEに対応してみます。


Android Manifestの修正

複数のタイプに対応することを宣言するためにAndroidManifestのandroid:name="android.support.wearable.complications.SUPPORTED_TYPESにあるandroid:valueへカンマ区切りでテキストを繋げていきます。
ICONとRANGE_VALUEに対応することを宣言するため以下のように変更します。
AndroidManifest.xml

<meta-data
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="SHORT_TEXT,ICON,RANGED_VALUE" />


アイコンの作成

今回はICONをサポートするためにICONファイルを作成します。
アイコンはWatchFaceによっては透明度のみが使用され色情報が無視されたり別の色に置き換えられる場合が有ります。
このガイドラインは様々なデザインのWatchFace上で正しくアイコンを表示するために重要です。そのためアイコンはシルエットのみで情報が伝わるようにする必要があります。

Android Wear2.0はAPIレベル24になるため、Vector形式のアイコンを心配なく使用することができます。
Vector形式とすることで複数のピクセル密度を意識しなくて良くなる他、ファイルサイズの縮小やメンテナンスを容易にすることができます。
AndroidのVector形式は特殊な形式ですが、Android Studioを使えば簡単にSVGから変換して作成することができます。

プロジェクトで右クリックしNew-Vector Assetを選びます。


Android Studioで用意しているアイコンを使用する場合はMaterial Icon、独自のSVGやPSDから変換を行いたい場合はLocal fileを選びます。
今回はMaterial Iconの上矢印と下矢印のアイコンを作成し、50未満と50以上でアイコンが切り替わるようにします。
Iconをクリックして上矢印のアイコンを選択しNameにic_upと入力したらNextをクリックします。

Confirm Icon Pathが出たらFinishをクリックします。

同様に下矢印のアイコンも作成してic_downという名前にします。


アイコンへの着色

現在テストで使っているElements Analogはアイコンを色付けしないため、アイコンを見やすくするために色を白にしておきます。
ic_up、ic_down共に次のようにfillColorの値を#FFFFFFに置き換えます。
ic_up.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M4,12l1.41,1.41L11,7.83V20h2V7.83l5.58,5.59L20,12l-8,-8 -8,8z"/>
</vector>


ic_down.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"
android:fillColor="#FFFFFF"/>
</vector>

SampleComplicationProviderServiceの修正

求められるTypeにより出力する形式を変更するために、SampleComplicationProviderServiceのtypeを比較する条件式にTYPE_ICONとTYPE_RANGED_VALUEの場合を加えます。

SampleComplicationProviderService

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
SharedPreferences data = getSharedPreferences("pref", Context.MODE_PRIVATE);
int value = data.getInt("value",0);
if (type == TYPE_SHORT_TEXT) {
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(String.valueOf(value)))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}else if(type == TYPE_ICON){
}else if(type == TYPE_RANGED_VALUE){
}
}

TYPE_ICONの場合の値を埋めていきます。
ComplicationData.Builderを呼び出し、引数はTYPE_ICONとします。

ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_ICON)

ComplicationData.Builder内で渡された値がデータ型と一致するかの検証を行っており、値の過不足があった場合は実行時例外が発生します。
データ型ごとに必須の値を必ず設定し、必須と任意項目以外の値を渡さないように気をつけてください。
例えばデータ型がTYPE_ICONだった場合setShortText()は許可されていないため使用すると例外が発生します。
TYPE_ICONではアイコンだけを設定可能です。

drawableからICONを作成するにはIcon.createWithResourceを使用します。
引数として第一引数にContext、第二引数にdrawableのidを指定します。
SampleComplicationProviderService

}else if(type == TYPE_ICON){
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_ICON)
.setIcon(Icon.createWithResource(this, value<50?R.drawable.ic_down:R.drawable.ic_up))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);

同様にTYPE_RANGED_VALUEの処理を設定します。
TYPE_RANGED_VALUEではvalue, minValue, maxValueが必須項目でIconなど幾つかの値を任意で書き込むことができます。
すべてを組み込むと次の通り。

SampleComplicationProviderService

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
SharedPreferences data = getSharedPreferences("pref", Context.MODE_PRIVATE);
int value = data.getInt("value",0);
if (type == TYPE_SHORT_TEXT) {
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(String.valueOf(value)))
.setIcon(Icon.createWithResource(this, value<50?R.drawable.ic_down:R.drawable.ic_up))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}else if(type == TYPE_ICON){
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_ICON)
.setIcon(Icon.createWithResource(this, value<50?R.drawable.ic_down:R.drawable.ic_up))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);


}else if(type == TYPE_RANGED_VALUE){
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_RANGED_VALUE)
.setIcon(Icon.createWithResource(this, value<50?R.drawable.ic_down:R.drawable.ic_up))
.setValue(value)
.setMaxValue(100f)
.setMinValue(0f)
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}
}

これで複数のデータタイプに対応することが可能です。

ユーザーにデータタイプを選択させる。

Watch faceとData providerで複数のデータタイプがマッチする場合、Data typeは自動的に優先度が高いデータタイプが選択されます。
例えば、Data providerとWatch faceがどちらもSHORT_TEXTとICONに対応する場合、SHORT_TEXTの方がデータが充実しており優先度が高いとみなされSHORT_TEXT が使用されます。
しかしながら、アイコンだけで十分に状態を表現可能であるが、SHORT_TEXTしか対応していないWatch faceに対応するためにSHORT_TEXTもサポートしたいと言うような場合があります。
このような場合にはユーザーにデータタイプを選択させることが出来ます。
データタイプを選ばせるには、データタイプの種類分それぞれ1つのデータタイプに対応したServiceを作ります。


Serviceを修正する。

複数のデータタイプで、同じデータを出力する場合、Service側の処理はどれも同じという場合が多いです。
単に複数のServiceがあれば良いため、もとのServiceを抽象化して、データタイプごとに継承して複数のServiceに分けます。
SampleComplicationProviderService

public class SampleComplicationProviderService extends ComplicationProviderService {
public static class TypeText extends SampleComplicationProviderService{}
public static class TypeIcon extends SampleComplicationProviderService{}
public static class TypeRangedValue extends SampleComplicationProviderService{}


クラス全体だと次のとおりです。
SampleComplicationProviderService

package org.firespeed.dataproviders;


import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.Icon;
import android.support.wearable.complications.ComplicationData;
import android.support.wearable.complications.ComplicationManager;
import android.support.wearable.complications.ComplicationProviderService;
import android.support.wearable.complications.ComplicationText;


import static android.support.wearable.complications.ComplicationData.TYPE_ICON;
import static android.support.wearable.complications.ComplicationData.TYPE_RANGED_VALUE;
import static android.support.wearable.complications.ComplicationData.TYPE_SHORT_TEXT;


/**
* Complication Watch Face DataProviderがデータを提供するためのサービス
*/
public class SampleComplicationProviderService extends ComplicationProviderService {


public static class TypeText extends SampleComplicationProviderService{}
public static class TypeIcon extends SampleComplicationProviderService{}
public static class TypeRangedValue extends SampleComplicationProviderService{}
/**
* データを返してほしいときに呼ばれる
*
* @param complicationId 画面上に置かれたWatch Face Complicationごとに一意となるID
* @param type 表示するデータのType
* @param complicationManager ComplicationManager 結果を渡す
*/
@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
SharedPreferences data = getSharedPreferences("pref", Context.MODE_PRIVATE);
int value = data.getInt("value",0);
if (type == TYPE_SHORT_TEXT) {
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(String.valueOf(value)))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}else if(type == TYPE_ICON){
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_ICON)
.setIcon(Icon.createWithResource(this, value<50?R.drawable.ic_down:R.drawable.ic_up))
.build();
complicationManager.updateComplicationData(complicationId, complicationData);


}else if(type == TYPE_RANGED_VALUE){
ComplicationData complicationData = new ComplicationData.Builder(ComplicationData.TYPE_RANGED_VALUE)
.setIcon(Icon.createWithResource(this, value<50?R.drawable.ic_down:R.drawable.ic_up))
.setValue(value)
.setMaxValue(100f)
.setMinValue(0f)
.build();
complicationManager.updateComplicationData(complicationId, complicationData);
}
}
}


AndroidManifestの修正

あとはAndroidManifestにデータタイプごとのServiceを設定していきます。
android:name="android.support.wearable.complications.SUPPORTED_TYPESでタイプを別々に分けることで別のタイプをユーザーが選択できるようになります。
ユーザーが選択しやすいようにiconやlabelを書き換えるのも忘れないようにしてください。
AndroidManifest

<service
android:name=".SampleComplicationProviderService$TypeText"
android:icon="@mipmap/ic_launcher"
android:label="Text">
<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
</intent-filter>


<meta-data
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="SHORT_TEXT" />


<meta-data
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
android:value="0" />
</service>
<service
android:name=".SampleComplicationProviderService$TypeIcon"
android:icon="@mipmap/ic_launcher"
android:label="Icon">
<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
</intent-filter>


<meta-data
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="ICON" />


<meta-data
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
android:value="0" />
</service>


<service
android:name=".SampleComplicationProviderService$TypeRangedValue"
android:icon="@mipmap/ic_launcher"
android:label="RangedValue">
<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST" />
</intent-filter>


<meta-data
android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="RANGED_VALUE" />


<meta-data
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
android:value="0" />
</service>


<service android:name=".ReceiverService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/path"
android:scheme="wear" />
</intent-filter>
</service>



ComplicationでDataProvicerを選ぶとさらにどのデータタイプにするかを選択する画面が出てくるようになります。



SHORT_TEXT

ICON

RANGED_VALUE


BOSE QUIETCONTROL30を買いました

$
0
0
BOSEの新製品イヤホンQUIETCONTROL30を購入し2週間ほど使ってみました。
一言で言うならこれは買ってよかった。

購入のきっかけ

そもそもの発端はそれまで使っていたSONYのMDR-EX31BNが突然ノイズを発生するようになったこと。
分解してみたところノイズキャンセル用のマイクに繋がるワイヤーのハンダが剥がれており接触不良を起こしていた。
そこでハンダ付けを試してみたのだけれど、ノイズは出なくなった代わりにノイズキャンセルが有効にならなくなってしまった。


MDR-EX31BNはケーブルが絡まりやすいことを除くとかなり気に入っていたのですが購入後1年半程度での故障は残念。しばらくノイズキャンセル無しで使ってみたものの、それまでノイズキャンセルに慣れていたせいで、電車に乗ると電車内のレールが軋む音やモーター音が気になって妙に疲れてしまう。
電車移動中は動画を見る事が多いのだけれど、ノイズのせいで声が聞き取れず音量を上げ気味になるのも耳のことを考えるとよくなさそう。
ということで買い替えすることにしました。
買い替えの条件はノイズキャンセル機能付き、Bluetoothによる無線タイプ、インナーイヤータイプ。ここまでしぼると中々いい商品がありません。
実際、SONY製品以外はノイズキャンセル機能がイマイチだし、SONYはMDR-EX31BNの後継機種を出していない状態。


そこに、すべての条件に一致したBOSE QUIETCONTROL30が発売されました。
価格は3万円台中盤とそれまで1万円未満のイヤホンしか使っていなかった身としては高いイヤホンですが、タイミング的にドンピシャだったこと、QUIETCONTROL20のノイズキャンセルがMDR-EX31BNより優秀だったこともあり思い切って買ってみることにしました。
ちょっと特殊なのが、左右をつなぐのがワイヤーではなく襟のような筐体になっていることです。この使い勝手も気になるところ。


接続する

接続は簡単なNFC方式
BluetoothのペアリングはSONY製品での採用が多いNFCによるペアリング方式。
単にかざせばいいだけなので非常に楽です。NFCに対応していないMacBookProやNFCによるペアリング機能がないiPhoneなどは通常のBluetoothと同様に手動で接続することもできます。
しかし、後述の理由により、このNFC機能そこまで重要じゃないです。



ノイズキャンセルを試す

ホワイトノイズが少ない

早速接続してみたところ、すぐに気づいたのがホワイトノイズの少なさ。
アクティブ式のノイズキャンセルイヤホンは外部マイクで録音した音に対して瞬時に逆位相の音を再生することで音を消すという仕組みなんですが、完全に逆位相の音を出すことは難しく、静かな場所では逆にサーッというノイズ音が乗ってしまうという問題があります。
MDR-NC33VやMDR-EX31BNの場合、人の少ない屋内では真っ昼間でもノイズキャンセルできえる騒音よりホワイトノイズのほうが大きくなる状態。
それに対してQUIETCONTROL30はホワイトノイズが少なく真夜中で殆ど騒音が気にならない状態でもノイズキャンセルを有効にしたほうが静かになります。
イヤホンを外した時にPCのファンや水道管に水が流れる音など、QUIETCONTROL30が消していたノイズが突然聞こえて、こんな騒音があったのかと気付かされるほど


地下鉄で試す

ノイズキャンセルぶりを地下鉄で試してみます。
駅で歩いている時にノイズキャンセルを有効にすると、服が擦れる音がキャンセルされて歩いていることに違和感がある不思議な感覚を受けました。
そもそも、服が擦れる音なんてそんな音がある事自体気づいていなかった
駅の改札で構内アナウンスが小さく聞こえたので、階下のホームからアナウンスが漏れ聞こえているのかな?と思っていたらマイクが頭上にあったりと中々のインパクト。
車内では走行音が静かになるのはもちろんですが、MDR-EX31BNではあまりキャンセルされなかった車内アナウンスや乗客の声も一気に静かになります。
ノイズキャンセルのされかたが自然なのも凄い。
MDR-EX31BNの場合ノイズキャンセルするとたしかに静かになるものの機械的に音をシャットアウトしているなーという感じだったのが、QUIETCONTROL30はノイズキャンセルしていることを意識すること無く、普通に静かな空間にいるように感じる。本当にうるさいのかな? とイヤホンを外してみると想像以上の騒音が入ってきて思わず驚くほど。


MDR-EX31BNもけっしてノイズキャンセル力は弱くはありませんでした。競合他社と比較すると、いまでもノイズキャンセル機能は優秀です。ただ、QUIETCONTROL30はそれを遥かに超えていました。
競合他社がノイズキャンセル力が1とすると、MDR-EX31BNは3、QUIETCONTROL30は6。


繁華街で試す

繁華街に出るとさらにノイズキャンセル力の強さを実感します、歩道を歩いている時に音楽などをかけていなくてもノイズキャンセルを有効にするだけで車道を走る車の音がほとんど聞こえなくなる状態。
乗用車はもちろん、バスやトラックのような大型車も目の前を走っているのにかなり離れた場所を走っているようなくらいまで消音されます。怖くなってすぐにノイズキャンセル機能を弱めました。
MDR-EX31BNの時は道を渡ったり歩道が細いところではイヤホンを外すようにしていたのですが、QUIETCONTROL30は歩道でさえノイズキャンセルを最高のまま歩くのは怖いです。
ノイズキャンセルを弱くしていくと今度は逆に通常よりノイズが大きくなるまで上げることができ補聴器みたいになります。


飛行機で試す

飛行機でも試してみました。
本当はBluetoothトランスミッターと組み合わせて試したかったのですが、乗った飛行機にオーディオサービスがなく単体で試してみました。
ここでもやはり印象は他の場所と同じ、圧倒的にノイズキャンセルできてすごく静かになります。
ただし、やや難しいのは電車にしろ飛行機にしろ完全に無音にはならないということ。
真夜中の秒針の音が気になることがあるように、完全に無音じゃない以上、この音でも気にし始めると気になります。
それでも、ノイズキャンセルしない場合と比べると飛行機を降りた後の疲れが俄然違いました。


ノイズキャンセルの違い

ノイズキャンセル力については圧倒的な性能差がありました。
ノイズの減り方もちがっていて、MDR-EX31BNは割り算、、QUIETCONTROL30は引き算という感じ。
例えばMDR-EX31BNは10の音量は5に、2の音量は1になるイメージで、大きな音は小さな音に、小さな音はもっと小さな音になって、小さな音でも音が残る。
それに対して、QUIETCONTROL30は10の音量は5に、5の音量は0にと言うように大きな音は小さな音になるのは同じだけれど、小さな音は殆ど聞こえないか意識の外に行くほどなくなってしまう。

価格の問題

1万円以下のノイズキャンセルイヤホンと比べるとQUIETCONTROL30は高いイヤホンだと思うんですが。
世の中を見ても、最高級の性能を持った製品が3万円ということは殆ど無い気がします。
たとえばイヤホンで言うと高音質モデルは10万円を余裕で超えますし、スピーカーで言えば3万円はエントリーモデルの範疇、デジカメでも3万円のモデルはややいい程度。
パソコンやテレビだとボトムエンドの価格です。
それがノイズキャンセルの部分だけとはいえイヤホンタイプではQUIETCONTROL30のノイズキャンセルは他にないレベルで、あれ?これはお買い得では と思えるようになりました。

音質は十分高音質

音質に関しては好みの問題も出てくるのであまり深いことは言えないのですが、文字通り十分高音質と思える音質に感じました。
この価格帯でこれよりももっと音質の良いイヤホンはいくらでもある用に思います。例えばaudio-technica IM Series ATH-IM02とか
無線式やノイズキャンセル方式はどうしても音質面では不利になるし、コストもそこでかかってしまうのでそれは仕方がないところ。
といっても決して音質が悪いわけではないです。MDR-EX31BNよりは明らかに音質が良い。ただノイズキャンセルの能力がインパクトが大きい割に音質に関してはそこまで大差がないです。
私の場合はこれで十分。


Bluetoothの接続が安定している

自宅ではMacBookPro、移動中はNexusを繋ぐことが多いのですが、従来のBluetoothイヤホンではこういうときのデバイス切替がうまくいかないことがよく有りました。
MDR-EX31BNの場合、MacBookProからNexusに切り替える時はNFCをタッチさせればいいのですが、逆にNexusからMacBookProに切り替える時はイヤホンをペアリングモードに切り替えてMacBookProから接続しないとうまく切り替わらなかったりデバイスの情報を一旦リセットしないといけないことがあったりしました。
また、今どちらのデバイスとつながっているかを確認することが難しく、実際に音を鳴らしてみるまでわからないため、公共の場では最初に音量を小さくしてから再生して、ちゃんとつながっていることを確認してから音量を上げるようにしていました。


それがQUIETCONTROL30の場合は電源をつけるとConnected to MacBookPro and Nexus5というように音声案内で複数同時につながっているのがわかります。(設定で日本語の音声案内にすることも可能)
あとは音がなった方を再生するというスマートな仕組みになっているようでこれと言ってどっちと繋ぐかという操作をする必要もありません。
電源ボタンを押すとConnected to MacBookProのように音声案内が行われ特定の端末と明示的に接続することも出来ます。
実利用においてはQUIETCONTROL30の電源をつけたらあとは再生したいデバイスで再生すれば良いだけ 今までの苦労は何だったのかと思うほどスマートです。
おかげでBluetoothの再接続は必要なくなり、NFCの出番もなくなりました。


首掛け式は便利

購入時に不安だったのが首掛け式の本体。見慣れない形状だったので首にかかって気持ち悪いのではないか?カバンでかさばるのではないか?と心配していました。
ただこれは、少なくとも秋の時点では違和感が全く無いです。
全くないというのは誇張でも何でも無く出かけようとしてイヤホンを探しても見つからず、はっと思って首を触ってみると実はすでに首にかけていた なんていう漫画に出てくるおじいさんのメガネみたいなことが実際にありました。



カバンの中でかさばるのではないか?というのも不安だったけれど、たしかに多少かさばるもののバッグ内にすっと収まるサイズだったし、ケーブルをまとめたりしなくていいので収まりはむしろ良いです。
ちょっと聞くのを中断 というときも耳からイヤホンを抜いて首にかけた状態に出来るのでカバンに収めずに済ませることも増えました。
細かい点ですが左右が分かりやすいのもありがたいです。
あとは襟の無い服を切ることが多い夏場にどう感じるかですね


大切に持ち運びたい人は厚手の緩衝材で作られた専用ポーチも付属しています。
これを使うとかなりかさばります。
体感的にはCDウォークマンとかのサイズがあります。
イヤホンの形状から中央部分があくためここに他に持ち運びたいものを入れておくことでスペースを多少は有効活用できそうです。
MacBookAirのACアダプタとかを一緒に入れることも出来ますし、

モバイルバッテリーとUSB給電機にUSBケーブルを入れたりも出来ます。



LEDがきれい

高輝度なLEDをつかっているようで充電や電源ON時に点灯するLEDが色鮮やかでかっこいいです。
実性能には関係ないけれど細かいところで所有欲をくすぐってくれます。


ボタンを見ずに操作できる。

再生や巻き戻し、音量の調整にノイズキャンセルの調整ができるリモコンが右のケーブル部分についています。
音量とノイズキャンセルではアップダウンの幅を変えるとか、ボタンを片面と側面にのみ配置するなど工夫されていてボタンを見ずに操作ができます。



ここがいまいち

全体的に良いのですがこれはどうなの?って思う部分もあります。


ピーチスキンの耐久性は大丈夫なのか

本体表面は薄いゴムで覆われたソフト素材になっています。
これは高級感にはつながっているものの、この手の素材はベトベトに溶けてくることがあるので心配です。
ThinkPadのように長期間経過してもベトベトになりにくいものもあるので、QUIETCONTROL30も同様に耐久性が高い可能性もありますが、はたして。


充電端子の質感が悪い

この製品はmicro USBで充電するんですが、USBの蓋がくねくねしたゴムだけでちょっと使っていると抜けたりちぎれたりしそう。 取り付け、取り外しのときの感触もよく割りません。
次期的に難しいけれど、USB typeCじゃなかったのも残念。
蓋を開けたあとに差し込みにくい上に向きが見えづらいので逆向きに挿そうとしてしまうことが多発しています。



デバイス接続時における音声案内の弊害

これはBOSE QUIETCONTROL30の問題というよりMac側の問題もあるように思いますが、QUIETCONTROL30はデバイスと接続された時に Conneted to MacBookProのように接続されたデバイス名が読み上げられます。
Nexus5と接続している時でもMacBookProが接続可能な状態になるとNexus5の音声が再生したままで、Connected to MacBookProという案内が行われます。


ところがMacはスリープ時に定期的にBluetoothと繋ぐことがあるようで、Nexus5で動画を見ているのにカバンの中でスリープになっているMacBook Proと定期的に繋がってConnected to MacBook ProとDisconnected MacBook Proが交互にながれて煩わしいことがありました。


ノイズキャンセルの強度が直感的じゃない

これはノイズキャンセルが自然すぎるためなんですが、ノイズキャンセルの強さを弱めるのに下ボタンを押すのが違和感あって、何度も押し間違えました。
どういうことかというと、ホワイトノイズが少ないため下ボタンを押すと外の音が大きくなっていくだけで、ノイズキャンセルの強さを調整しているという感覚がないんです。逆に外の音を聴くために、外の音量を上げ下げしていると錯覚してしまうので音量を上げるのに下ボタン? と混乱してしまいます。


おすすめ度

70%(条件付きでおすすめ)
価格は高いし、耐久性や気になるポイントも多々ありますが、それでもこのノイズキャンセルを味わえるインナーイヤータイプのイヤホンが他にないことを考えれば、これ以外のイヤホンを選ぶ気持ちはなくなりました。
あとは長期的に使ってみて評価を決めようとおもいます。


Wear2.0の概要とスタンドアローンアプリの作りかた

$
0
0
この記事は Androidその2 Advent Calendar 2016 の7日目の記事です。

Android Wear

Google I/O2016にてAndroid Wear2.0がアナウンスされました。
最近のAndroidといえば、バージョンの命名規則が5.0から変わってちょっとした機能の追加でバージョン番号が大きく変わるようになりました。
それまではAndroidでは1単位の変化はUIを含めた大幅な変更が加わったときで割と大きな機能追加が行われても0.1単位でバージョンが増えていくというルールになっていました。
それが、5.0以降はUIに大きな変化が加わらなくても1単位でバージョンが変わるようになりました。
多くの人が4.4から5.0への変化より5.0から7.1への変化の方が小規模な変化と感じるのではないでしょうか。
それに対してAndroidWearについては従来のAndroidをベースとしたバージョン番号の考え方が継続されています。
実際にAndroidWearはベースとなるAndroidが5.0や6.0になったときにもバージョン番号は0.1単位でしか増えることがなく、1.4と言いながら当初のバージョンとはもはや別物と言えるレベルで機能が強化されています。

そして、AndroidWear2.0はAndroidWearとして初めてのメジャーバージョンアップとなります。
それだけに、追加される機能や変更される内容は大掛かりな変化となり、最近のAndroidスマートフォンではあまり見ることのないレベルでの大掛かりな変化が行われ、ユーザー目線でも開発者目線でも別物レベルになりました。
現在はデベロッパープレビューという状態で、alpha3がリリースされています。
当初の予定では2016年中に正式版がリリースされる予定でしたが2017年前半にスケジュールが変更されました。

Wear2.0で変わる大きな変更点は次のとおりです。
システムUIの大幅な変化。
Complications APIの導入によるGlanceable性の向上。
スタンドアローンアプリの強化とそれに伴う利用形態の拡大。
配布形式の変更。

システムUIの大幅な変化

システムUIは斬新に変更され、白を基調とした軽快な印象がある1に対して黒を基調とした引き締まったデザインに変更されます。
デザインの印象としてはよりフラットになり未来感が強調され、5.0からのMaterial Designより3.0からのHoloテーマに近い印象を受けます。
カードUIのような画面を分断するデザインが削られ、画面全体を使ったWearならではのデザインに取り替えられています。


実際の操作感としては、明らかに1.xよりコンテンツが見やすくなりました。
1.xの時はメッセージが来た場合、Wearでタイトルを見て本文を見る必要があればスマートフォンを取り出していましたが、2.0を使うようになってからはWearで本文まで見るようになり、長文であったり返信が必要な場合以外はWearで済ませることが増えました。

この流れはAndroid Wearの一連の流れに沿ったものになります。1.0では極端なほど機能が制限されており、アプリランチャーすらすぐには開けない場所にあるなどユーザーや開発者がWearに多機能さを求めないようなデザインがされていましたが、それらはバージョンを経るごとに緩和されて次第にWearで行える操作を増やしてきました。

通知については追加機能を使わない限りはアプリ側の対応は必要ありません。自動的に2.0風の見た目に変わります。
しかしActivityに関しては自動で2.0風になったりはしないので見た目を合わせるなら作り込みが必要になります。
サポートライブラリーが用意されているため、単純に見た目を揃えるだけならそれほど苦労はしません。ただし操作感が大きく変わるため、ユーザーが使いやすいデザインにするためには画面構成を1から考え直す必要があります。

Complications APIの導入によるGlanceable性の向上

Wearでやれることが増える一方でWearならではの一瞬で情報を受け取れるGlanceable性もComplicationsAPIによって向上しています。
Complications APIはWatch face上に任意のアプリの情報を表示することが出来る仕組みです。

ちょうどスマートフォンにおけるホームウィジェットのような存在です。
これまで、Watch face上に情報を表示するには、Watch face自体がデータを取得して描画するまでのしょりを行う必要がありました。 データ提供元はデータを表示したいだけなのにWatch faceまで用意しないといけないし、Watch face作者からしてみたら、よりユーザーのニーズに答えるには多種多様なサービスの情報を表示する機能を付ける必要があり、ユーザーからしてみたら好きなデザインのWatch faceで好きな情報を得ることが出来ないという問題がありました。
Complications APIを使うとデータをWeb APIなどのサービスから取ってきて定形に合わせる処理をData providerアプリが行い、Watch faceは定形で渡されたデータを単に表示するだけでよくなります。


Android Wear1.xの場合
Watch face作者はデータ提供元それぞれの取得方法を調べて実装する必要があり、実装コストが大きく、Watch face側が対応していないサービスについて情報を表示することはできませんでした。
そのためユーザーが見たい情報を表示できるとは限りませんでした。


Android Wear2.0の場合
データ提供元はデータを取得してComplications APIに提供するData provider APKを作り、Watch face作者はComplications APIから渡されるデータを表示します。
データ提供元はデータさえ渡すだけでよく、Watch faceを作らなくても良くなりました。
Watch face作者はComplications APIからのデータを表示するだけで様々なデータを表示できるようなり、ユーザーはどのWatch faceでどのData providerを表示するかをカスタマイズできるようになりました。

Complications APIについてはNotificationとの使い分けが気になるところですが、Notificationが全てのアプリが時系列で並ぶのに対してComplicationsは特定のアプリが同じ場所にとどまり続けることが違います。
このため、ユーザーはWatchを覗くことで確実に現状を把握することが出来るようになります。
例えば、メールが来ていないこと を確認した場合に、従来の方式ではメール以外を含む全ての通知を見てメールの通知がないことを確認する必要がありました。Complications APIであれば、メールの新着数を表示させることで一瞬でメールが来ていないことを確認することが出来ます。
その分、特定アプリに場所を専有されるため、全てのアプリの情報を表示することは出来ません。その場合はNotificationが使われることになります。

詳しくは後ほど、実際にData Providerを作ってみます。

スタンドアローンアプリの強化とそれに伴う利用形態の拡大

Wear のAPKでインターネットへ接続できるようになりました。
これにより、Data syncのようなWear独自のコードを実装すること無く、スマートフォン用のコードと同じコードでサーバーからデータを取得できます。
インターネットの接続は必ずしもWearにWi-FiやLTEなどがついている必要はなく、直接インターネットに接続しているかスマートフォンを経由して接続しているかはアプリ作者は意識しなくても良くなります。(ちょうどスマートフォンのアプリをWi-Fi経由かLTE経由かを意識せずにコードが書けるのに似ています。)
これにより、データを中継するためのスマートフォン用APKを用意しなくても良くなり、スマートフォン向けのロジックをそのまま流用してウェアラブルでデータを取得できるようになります。
Wi-FiやLTEで接続されている時はスマートフォンが無くてもデータの通信ができるため、Wearだけを身に着けてスマートフォンは家においたままにしておくというような利用形態が今後広がってくるかもしれません。
これはシステムUIの変化でWearでの操作をしやすくしていることにも合致します。

配布形式の変更

すでにAndroidWear 向けのアプリを作っている人には悲しいお知らせです。Android Wear2.0向けのアプリをGooglePlayで配布する場合、従来のバージョンと互換性ありません。(Notificationのみを使用しておりWear向けAPKを含まないアプリを除く)
Android Wear1.x向けに作られているAPKはそのままではAndroid Wear2.0にはインストールされず必ず対応が必要になります。


Android Wear1.x向けのAPKはスマートフォン内のAPKに内包する形でGoogle Play storeにアップロードしていました。
スマートフォンはGoogle Play storeからAPKをダウンロードした時に、スマートウェア向けのAPKが含まれていたらそれを取り出してスマートウォッチへ転送することでスマートウォッチのインストールを行っていました。


Android Wear2.0ではWear向けのAPKをMobile向けに内包する必要はなくなり、それぞれのAPKをどちらもGoogle Play storeにアップロードするようになります。
Wear 1.xとWear2.0のどちらも対象とするアプリの場合は1.xのために依然Wear向けのAPKをMobile向けに含める必要がありますが、それはWear2.0では無視されるため別にWear2.0用のAPKをアップロードする必要があります。
もし、スマートフォンを必要とせずAndroid Wear2.0のみで動作するアプリを作成する場合はWear向けのAPKだけを直接Google Play storeにアップロードします。


このようにWearとPhoneのAPKが別れた理由としては、次のような理由が考えられます。
1.非WearユーザーにとってはWear向けのAPKが一緒にダウンロードされるのは冗長だった。
2.今後スマートウォッチ以外の様々なウェアラブルプラットフォームが登場した場合に、それぞれのAPKを全てスマートフォン向けのAPKに含める方式は破綻する。
3.スマートフォンにはインストールしたいがウェアラブルにはインストールしたくない、あるいはその逆といった柔軟な対応をユーザーが行えるようになる。
4.ウェアラブルのuses-featureやminSdkVersionなどによって異なるAPKを使い分けることができるようになる
5.スマートフォンにアプリが入っていなくても動作するウェアラブルアプリ開発の促進。


とはいえ、開発者にとっては大変です。

従来のウェアラブルアプリを2.0対応するには

すでにWear1.x向けにアプリを作っている人の場合、あるいは今後1.Xと2.0のどちらにも対応したウェアラブルアプリを作りたい場合、次のような手順を取ります。
ウェアラブルのbuild.gradleでdependenciesのcom.google.android.support:wearableを2.0.0-alpha3に変更する。


Android Studioのバグでエラーが表示されますが、そのまま動作します。

compile 'com.google.android.support:wearable:2.0.0-alpha3'



Product flavorsでSdkVersionを元にWear1系と2系を分ける
2系はSdkVersionが24以降となるためminSdkVersionに24を指定すると2系のみにインストールされるようになります。
1系から2系にアップロードされる端末を想定してVersionCodeは2系の方を上げておきます。
これによりSdkVersionが24になった端末はより新しいversionCodeのAPKをインストールしに行くようになります。
注意すべき点として、こんごバージョンアップを行う上でバージョン番号が逆転しないようにするために、番号は大きめにとっておくようにしてください。
例えばWear1を1,Wear2を2などのようにしておくと、今後のバージョンアップでWear1を3にしたタイミングでWear1よりWear2向けのAPKのバージョンコードが小さくなってしまいます。
一般的には最上位の桁をminSdkVersionと一致するようにしておくなどして必ずminSdkVersionが大きな数字を持ったAPKの方がバージョンコードが高くなるようにします。

productFlavors {
wear1 {
versionCode 21001 // 次のバージョンアップでは21002
minSdkVersion 21
}
wear2 {
versionCode 24001// 次のバージョンアップでは24002
minSdkVersion 24
}
}

スマートフォン向けのbuil.gradleを開いてwearApp projectでFlavorを指定するように変更し、Wear1のAPKを内包するようにする。

wearApp project(path: ':wear', configuration: 'wear1Release')

※Google Play storeの取扱方式については現在議論中らしく今後変更される可能性が高いです。


あとはMultiple APKの仕組みを利用してスマートフォン用のAPKとFlavorがWear2で作成したWear向けの署名済みAPKをどちらもGoogle Play Storeにアップロードします。


また、内部ロジックにおいても スマートフォン側のアプリが存在していないことがある。ということを考慮した開発を行う必要があります。


アプリを作ってみる

それでは実際にWear2.0ならではのアプリを作ってみましょう。
今回もComplications APIを利用したData providerを作成します。
以前の連載ではスマートフォンのデータを表示するDataProviderを作成しましたが、今回はWear2.0で追加された直接インターネットへ接続できる仕組みを使ってWear単体でインターネットから天気予報を取得するDataProviderを作成します。


新規プロジェクトの作成

Android Studioで新規プロジェクトを作成します。
Target Android DeviceにはWearを選択し、MinimumSDKはAndroid 7.0 Nougat preview を指定します。(何と素晴らしいことでしょう)





Add an Activity to WearではData ProviderはActivityを必要としないためAdd No Activityを選びます。
Finishを押して新規プロジェクトを作成したら、appのbuild.gradleを開いて修正を行っていきます。

build.gradleの修正

折角なのでdefaultConfigにjackOptions{ enabled true]を記載してjackを使いましょう。

defaultConfig {
//中略
jackOptions {
enabled true
}
}



compileOptionsでJava1.8を使用できるようにします。

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

dependenciesを記載していきます。


com.google.android.support:wearable:1.4.0
を2系対応に変更します

compile 'com.google.android.support:wearable:2.0.0-alpha3'
provided 'com.google.android.wearable:wearable:2.0.0-alpha3'

Webサーバーからのデータ取得はRetlofit2とRxAndroidを使用してHTTPクライアントはokhttp、JsonのデコードはGSONを使います。
このあたりはスマートフォン向けと同じですね。

compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.okhttp:okhttp:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'

build.gradle全体では次の通り

apply plugin: 'com.android.application'


android {
compileSdkVersion 25
buildToolsVersion "25.0.1"
defaultConfig {
applicationId "jp.co.sample.wear2"
minSdkVersion 24
targetSdkVersion 25
versionCode 1
versionName "1.0"
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.google.android.gms:play-services-wearable:10.0.1'
compile 'com.google.android.support:wearable:2.0.0-alpha3'
provided 'com.google.android.wearable:wearable:2.0.0-alpha3'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.okhttp:okhttp:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0'


}



続いてAndroid manifestを修正します。
ライブラリーの使用を宣言し、

<uses-library
android:name="com.google.android.wearable"
android:required="false"/>



DataProviderとなるProviderServiceを宣言して、DataProviderとして提供するデータ型にSHORT_TEXTとLONG_TEXTを指定します。
更新間隔は14400(3時間)としておきます。

<service android:name=".ProviderService"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/>
</intent-filter>
<meta-data android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="SHORT_TEXT,LONG_TEXT"/>
<meta-data android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" android:value="14400"/>
</service>

AndroidManifest.xml全体は次の通り

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.co.sample.wear2">


<uses-feature android:name="android.hardware.type.watch"/>


<uses-permission android:name="android.permission.WAKE_LOCK"/>


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />


<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.DeviceDefault">
<uses-library
android:name="com.google.android.wearable"
android:required="true"/>
<service android:name=".ProviderService"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/>
</intent-filter>
<meta-data android:name="android.support.wearable.complications.SUPPORTED_TYPES"
android:value="SHORT_TEXT,LONG_TEXT"/>
<meta-data android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS" android:value="14400"/>
</service>
</application>


</manifest>



Gsonの受け皿を作る。
今回はLivedoorのお天気Webサービスを使用しました。
戻り値のJsonをもとに必要な形式をクラスで作ります。


お天気Webサービスは様々なデータを返してくれますが、今回はテロップと詳細のテキストだけを切り抜きます。


新規クラスでResultWeatherを作り、Jsonの形式に合わせた形にします。

package jp.co.sample.wear2;


import java.util.List;


/**
* Created by kenz on 12/6/16.
*/
class ResultWeather {
List<Forecast> forecasts;
Description description;
static class Forecast{
String telop;
}
static class Description{
String text;
}
}

お天気Webサービスへのデータ取得を行うクラスを作ります。
Networkクラスを作成し、その中にjson/v1へcityをクエリパラメータとして問い合わせを行いResultWeather
を返すようにApiインターフェイスを作成します。



interface Api {
@GET("json/v1")
Observable<ResultWeather> getWeather(@Query("city") String city);
}
static final Api api;

Httpのログとかタイムアウトとかコンバーターなどなどを指定していきます。
基準となるURLはhttp://weather.livedoor.com/forecast/webservice/としています。
Jsonはキャメルケースで帰ってくるため、それも指定しておきます。(今回は使いませんが)
注意点としてウェアラブルは性能が低い上にサービスは実行速度も絞られるためタイムアウトの時間は広めにとっておいたほうが良いです。
どのみち、データプロバイダーの場合はレスポンスは求められないです。



static {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {Log.d("newtwork", message);});
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(logging).connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).build();
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://weather.livedoor.com/forecast/webservice/")
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
api = retrofit.create(Api.class);
}



Network全体は次の通り

package jp.co.sample.wear2;


/**
* Created by kenz on 12/6/16.
*/
import android.util.Log;


import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;


import java.util.concurrent.TimeUnit;


import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;
class Network {
interface Api {
@GET("json/v1")
Observable<ResultWeather> getWeather(@Query("city") String city);
}
static final Api api;
static {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> {Log.d("newtwork", message);});
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(logging).connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).build();
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://weather.livedoor.com/forecast/webservice/")
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
api = retrofit.create(Api.class);
}
}

最後にデータプロバイダー部分を作成します。
見ての通り、データを取得する部分はごく普通にRetlofitとRxAndroidのそれです。
取得する天気は私の実利を兼ねて福岡の天気を取得しています。
どの地域を取得するかはCityコードを変えることによって変更できますので好みのコードに変えてみてください。

package jp.co.sample.wear2;


import android.support.wearable.complications.ComplicationData;
import android.support.wearable.complications.ComplicationManager;
import android.support.wearable.complications.ComplicationProviderService;
import android.support.wearable.complications.ComplicationText;


import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


/**
* データ提供を行う
* Created by kenz on 12/6/16.
*/


public class ProviderService extends ComplicationProviderService {


@Override
public void onComplicationUpdate(int complicationId, int dataType, ComplicationManager complicationManager) {
// 福岡市のデータを取得
Network.api.getWeather("400010").
subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
if (result.forecasts.size() < 0) {
return; // データを取れなかったら何もしない
}
ResultWeather.Forecast forecast = result.forecasts.get(0);
ComplicationData complicationData;
// データを取得できたら定型文に整形して
if (dataType == ComplicationData.TYPE_SHORT_TEXT) {
complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setShortText(ComplicationText.plainText(forecast.telop))
.build();
} else if (dataType == ComplicationData.TYPE_LONG_TEXT) {
complicationData = new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
.setLongTitle(ComplicationText.plainText(forecast.telop))
.setLongText(ComplicationText.plainText(result.description.text))
.build();
} else {
return;
}
// Complications に投げる
complicationManager.updateComplicationData(complicationId, complicationData);


});


}
}

Wear特有のコードはComplicationData complicationData;以降の部分で、単純にデータを投入しているだけ。
それでは実際に動かしてみましょう。
Elements AnalogでDataProvidersにWeatherを選ぶと・・・
ちょっと日本語がマッチしていない感じもしますが、無事にデータを取得することができました。
MobileのAPKは使用していないためスマートフォンがつながっていなくてもWi-Fiがあればデータを取得できます。


サンプルコードをGitHubにアップしました

6日目のカレンダー こわくない! Fragment
8日目のカレンダー

下手くそに思われない運転方法(初級編)

$
0
0
この日記は、下手くそに思われない運転方法に触発されて書いています。
そろそろ、免許を取り始める人も多いと思うので、誰でもできる簡単な運転方法を紹介したいと思います。


伝えること

運転をしていると、運転手は酔わないのに同乗者が酔うということが多くあります。
最大の原因は運転手は次どのように動くか分かっているのでそれに備えて力を入れることができるけれど、同乗者はそれがわからないということ。
そのため、同乗者に次どのような動きをするか早めに伝えることが酔わせない第一歩になります。

早めの方向指示器

まずは方向指示器、交差点で曲がる時は早めに方向指示器を付けます。
教習所では30m前と言われていますが、場合によってはもっと早くていいと思います。
具体的にはブレーキを踏むよりも先に方向指示器をつけること、もちろん曲がりたい交差点より前に別の交差点がある場合などは誤解を与えるのでその限りじゃありませんが、出来るならばブレーキを踏む前に方向指示器は2秒以上前には点灯させておきたいところ。
これで同乗者は次曲がるから減速するということを知ってそれに備えることができます。

ヘッドライトは早めに

運転手はずっと道路上を見ているため目が順応して多少暗くても意外と景色が見えたりします。
けれども、同乗者は明るい携帯画面と前を交互に見たりするため概ね運転手より前の景色が暗く見えます。
景色が見えないと次の挙動が予測しづらくなるし、不安を感じて酔いやすくなります。
具体的には太陽が沈んだらライトを点灯するくらいで早すぎないです。

ワイパーも早めに

これも前を注視しているドライバーだと多少水滴がついていてもちゃんと前方が視認できるけれどあちこち脇見をしている同乗者だとちょっとの雨で前が見えづらく感じて不安になります。
まだ見えるから大丈夫 ではなく、水滴が見えたらワイパーを付けるくらいの速さで

車間距離を取る

車間距離を取ることで、助手席の人は前の車が止まった時にブレーキが間に合うだろうか?と不安にならずに済みます。
また、車間距離を取ることで遠近法で前の車が小さく見えて景色がよく見えるようになり開放的な気分でリラックスしてドライブを楽しむことが出来るようになります。

ブレーキは強く早めに

急ブレーキは急ハンドルと同様、危険運転の代名詞として言われていますが、それのせいでブレーキが弱すぎる人のほうが多いです。
踏み始めのブレーキが弱いと同乗者はこのままではぶつかる と不安になってしまいます。
具体的にはブレーキの踏み増しは最初の2秒で終わらせてしまって、そこからはブレーキを一定あるいはちょっとずつ抜いていきます。
そのためには、最初にやや強めのブレーキを掛ける必要があります。
いきなりブレーキを踏むと追突されるのではないか?と思う人もいるかもしれませんが、後続車が極端に車間距離を狭めていない限りはブレーキランプの点灯で前の車の減速に気付くのでむしろ安全です。
逆に最初はゆっくりブレーキを踏んでいたのに後からブレーキを踏みたすと後続車はブレーキランプが点灯したタイミングで、ブレーキはゆっくりと認識してしまい、その後踏み足したタイミングに気付くことができないので追突される原因になります。

アクセルは一定に(中級)

加速時はあまり関係ないのですが、一定速度で巡航する時はアクセルの踏んでいる量が変わらないように一定の角度を保つようにします。
細かい前後の揺れは映画館で後ろの人が座席を何度も蹴りつけるような気持ち悪さを同乗者に与えます。
また、アクセル開度が一定になることで空気の流入量が一定になるので燃費も改善されます。

ハンドルはゆっくり切って一定の角度を保つ(中級)

慣れるまでは難しいですが、ハンドルの切り足しは同乗者に強い不快感を与えるので、可能な限り一定の角度を保つようにします。
ハンドルをゆっくり切るコツは、ハンドルの横側をちゃんと持って、曲げる時は曲がりたい方向の逆の手で持ち上げるようにハンドルを回すこと。
振り下げる動作は重力がかかる分動きが急で雑になります。持ち上げるようにハンドルを回すことで自然とユックリとしたハンドル操作が可能になります。

疲れさせないこと

上級テクニックとしてわざと疲れさせるというのもあるのですが、まずは疲れさせないことが大事
そのためには、

速度はユックリ

速度が速くなると揺れが大きくなるし、同乗者は緊張します。まずは飛ばしすぎないことが大事。
体感的に運転手より助手席のほうが、20km/h近く速く感じています。

こまめに休憩

運転手より同乗者のほうが疲れます。 自分が疲れを感じる前にコンビニなどで休憩すると同乗者はリラックスできます。
運転手が眠くなった時は躊躇せずに休憩して眠りましょう。
コーヒーなどのカフェインは即効性も持続性もないので頼らない方がいいです。

音楽の音量は助手席に任せる

特に自分が選んだ曲の場合、同乗者に嫌いな曲を大音量で聞かせることになりかねないです。
音量や曲選は同乗者にまかせましょう。

揺れる車はリクライニングさせない。

シートをリクライニングすると車と同乗者がより密接することになるので、揺れが直接同乗者に伝わって疲れやすくなります。
人は上下方向の揺れには得意でも前後左右の揺れには弱いので、上下によく揺れるシャコタン車などは特にシートのリクライニングを少なめにしてあげると疲れにくくなります。

荷物を置きすぎない。

荷室に荷物をおいていると揺れている時にガチャガチャと音を立て精神的に疲れることになります。
荷物は揺れないように固定するか、車の中に置かないようにします。

禁煙、禁芳香剤、掃除

匂いは車酔いの最大の原因です。特に強い匂いは激しい車酔いを引き起こします。
強烈な臭いがつくタバコはもちろん、芳香剤も車では強すぎることがあります。
同乗者が好きな芳香剤ならともかくそうでない場合は酔いの原因になります。
芳香剤ではなく、もっと匂いの穏やかなものを使って香りを演出することもできます。
私の場合はコーヒーの吸い殻を容器に入れていました。

そして何と言っても掃除をしっかりすること。エアコンフィルターの掃除も忘れずに。


今年買ってよかったものトップ5 2016

$
0
0

5位 ANKER 13ポートハブ


13個もUSBポートがいるのか?と聞かれそうですが、現状13+1ポートのうち12ポートが埋まっています。
内訳はキーボード、マイク、LANアダプタ、Lightning(Magic trackpad,iPhone7兼用)、Web カメラ、Huawei Watch、USB-TypeC ケーブル(Nexus6p用)、micro USBケーブルx5(Nexus5、Nexus6、Nexus9、GearLive、WacomTablet)

このあたりは仕事柄複数のスマートフォンを同時に接続してテストしたりすることもあるのも関連するので一般的とは言い難いですが、やはりこれだけの数があるのは安心感が違います。
今まで差し替え付け替えしていたのがつけっぱなしでよくなりました。
また、LANをWi-Fiから有線LANに変えたことで帯域の確保と速度の高速化を図ることが出来るようになりました。
有線LANはUSBハブ経由ででているので特に何か追加の作業は必要なく、家に帰ってきたらUSBハブを接続することでキーボードやスマートフォン、LANと一気に接続されます。



4位 Milight

いわゆるHueもどきですがなんといっても安いです。
昼白色と電球色の切り替えタイプなら9wタイプ(60W相当)で電球1灯あた1,680円(送料別)しかせず、単なる単色のLED電球と比べても価格差がそこまでありません。

Hueの場合4,062円なので

しかも、電球としても出来も悪くなくフリッカーなども感じず、配光角度も広く60Wタイプの電球と交換してもより明るくなったように感じます。
別売りのリモコンを使うことで操作できるのですが、Wi-Fiなどで使われる2.4GHz帯域を使用することで通常のリモコンと違って離れた部屋の電気をリモートで消すことが出来るようになりました。
さらに、別売りのWi-Fi変換アダプタを使うことでスマートフォンやPCからも操作ができるようになるようですが、コレはまだ試せていません。
時間帯によって昼間は昼白色、夜は電球色にじわじわ切り替えていくとかいうコードを書いてみたいと思っています。


3位 開くPCバッグ

当初はキャパシティ少なくて微妙かなと思っていたんですが、このポーチと組み合わせることで充電器やケーブル類をまとめて運ぶことが出来るようになりました。


15インチMacBook Proにα7s、変えレンズに加えて充電器やケーブル類まで含めて持ち運べます。
さらにDJI osmo mobileなどを入れることもあります。
このカバンの良い所は重たい荷物を入れてもあまり重さを感じないことで、バッグ自体が軽いこともあってバックパックと比べても遜色ありません。
そしてバックパックと比べると小柄で電車の中でも使いやすいのがいい感じです。

あと、バックが自立するので重たいMacBookProに小物が潰されるみたいな心配もなくなります。

今や出かけるときの9割はこの開くPCバッグを使っています。
難点としてはPCバッグなのだからUSBケーブルなどの線を簡単に出せるようにしてほしかったのと折り畳み傘を入れておくスペースが無いところ。

2位 Bose QuietControl 30 wireless headphones

強力なノイズキャンセル機能を搭載したイヤホン。
なんといっても最大の魅力はその卓越したノイズキャンセル力ですが、それ以外にも、ケーブルが散らかりにくい構造やBluetoothの安定性、複数デバイスの切り替えが容易なことなど普段使いにおいて凄く使いやすい。
電車にのる時はコレを付けておくだけで疲れ方が全然違います。
遅延が若干あるのと有線接続出来ないこと、充電端子が使いにくいのが難点。



1位 Ergodox infinity

今年一番買ってよかった買い物はこれ。
Ergodox
左右分離式のキーボードはネタ要素が大きいけれど、実際に使ってみるとすごく楽。
ちょうど肘掛けの前にキーボードが来るように配置することで椅子の肘掛けをパームレスト代わりにするリラックスしたスタイルでキー入力が出来るようになりました。
それと、この両脇が開いて胸を張った状態でPCを操作すると自然と猫背がなくなります。
肩こりに関してはトラックボールを使うようになってからすでに激減していたのですが、Ergodoxを使うようになってPCに起因する肩こりは皆無になりました。


キーバインドについてはオーソドックスなqwerty配列をできるだけコピーするようにしつつ、Enter,Space,Backspace,ESCを親指でタイプ出来る場所に配置しています。
コレで小指への負担も減りました。
最初はやはり慣れずにミスタイプが多かったですが、印字付きのキーに変えることでわからない時は目視しても正しいキーを押すようにして指を慣れさせていきました。
違和感なくタイピングできるようになるまで約3ヶ月位かかっています。


意外なメリットとしてキーの配置が一般的なキーボードのレンガ状ではなく、縦横が揃っている状態なので、どの指でどのキーを押すかがしっかり決まるようになりました。
例えばMキーは一般的なキーボードの場合、人差し指のホームポジションであるJキーと中指のホームポジションであるKキーの間に配置されていて、人差し指で押すか中指で押すか曖昧になりやすいのですが、Ergodoxの場合はJキーの真下にあるので必然的に人差し指で押すことになります。
これで指使いが正確になりました。
ある種の矯正器具みたいな役割を果たしてくれています。

加えて中央にスペースが出来たことで、ここに開発中のスマートフォンやマグカップを置くことが出来るようになりました。
マグカップが置けることがそんなに大事なの? って思うかもしれませんが、実際にやってみると安心感が半端ないです。
というのも、うっかりコーヒーをこぼしてしまったりヒヤッとする場面て大抵は視界外で手がコーヒーに当たったとか、マグカップを見ずに置こうとしたらそこに何か置いてあってマグカップが倒れたとかそういうことが多い。
それに比べて目の前にコーヒーを置くスタイルだとそういう心配がありません。
代わりにキーボードやトラックパッドが視界外に追いやられますが、それらは別に間違って手が当たったところでどうってことはないです。


番外編α7s


正確には、去年買ったものだけれど、購入したのが去年の終わりでちゃんと使い込んでいなかったので評価を保留にしていたもの。
フルサイズなのにAPS-C一眼レフ並のサイズ、画素数を犠牲にしても求めた高感度性能のどれもが満足。
特に高感度性能に関しては他社のハイエンドクラスも圧倒しており、感度を上げていってもノイズが凄く少ない写真がバシバシ撮れる。

高感度性能は暗いところでの撮影に効果を発揮するけれど、単にそれだけではなく、撮影の幅が大きく広がる。
いままでは、シャッター速度を稼ぎたい時は、レンズの絞りを明るくするの一択しかなかったのが、絞りはそのままで感度を上げるという選択肢を選べるようになった。
NEX-5NだとISO800を上限にして、それ以上はレンズを開放でとっても明るさが足りないときの緊急用として使っていたのに、α7sだとISO10000までは殆どノイズが目立たないので、明るさの調整はISOで行って、あとは作りたい絵に合わせて絞りを変えるようにしている。
これで撮影の幅がとても広がりました。

単に明るいだけじゃなく、階調が豊かなのも嬉しいところ。
強い光源が写っている時に白飛びしたり、逆光で黒つぶれしたりすること無く、なだからなグラデーションを描いてくれる。

NEX-5Nも好きだったけれど、やはりフルサイズは凄く良い。



Google I/O 2017への行き方

$
0
0

イベント概要

今年のGoogle I/Oについて、イベントの日程と場所、申込み受付日が発表されました。
イベント開催は5月17〜19日(現地時間)の3日間アンフィシアターで開催されます。
申込みは日本時間2月23日 AM3:00〜27日 AM10:00。

なぜ行くのか?

I/Oに行く理由については以前GoogleI/Oの公式サイトに載っていないことに詳しく書いています。
特に他の技術者に会えるというのが一番大きなポイント。
I/Oのセッションって、YouTubeで見られるよね? と言われればその通りなんですがやはり実際に行かないと得られないものも多いです。

どんなイベントなのか?

イベントでどんなことが発表されたかについてはニュース記事などに纏められていますが、実際に言ってどういう経験をするのかについては、なかなか知ることが出来ません。
私がまだI/Oに参加したことがなかった時、他の参加者の情報がほとんど存在せず、唯一天使やカイザーと呼ばれて を幾度も繰り返し読んで迷っていました。
そのため、私もできるだけイベントに行ったときのことを残すようにしています。
去年の渡航記はこちら


今年のイベントについて

2月23日から申し込み開始ということで、今年は珍しく早めに申込みが開始されそうです。
特に日本から行く場合、当確がわかってから、キャンセル不可の格安航空券を早めに確保出来ると旅費が安くなるので、当確が早めにわかるならうれしいです。

申し込み詳細についてはまだ発表されていませんが、スケジュールを見る限り今年も抽選方式になりそう。
詳しい情報については今後も追っていきたいと思っています。

イベント会場は今年もアンフィシアターで3日間。
去年の経験から言うと、熱くて寒いです。 湿度が低いので日差しが照ると照りつけて暑いけれど、日陰では風が冷たい(日がある)。
温暖差が激しいので調整できる服を着ていくことが大切ですが、日本と違って湿度がとても低いので多少厚着しても蒸れて暑いということはなく、長袖や帽子は風から寒さを守るにも日差しから暑さを守るにも役立ちました。

あと、私が泊まったホテルの周囲にもI/O会場の周囲にも店が皆無で、生活必需品は現地で買えばいいやん と思っていたらまるで手に入りませんでした。
Aloft santa clalaには歯ブラシがなく、歯ブラシが売っている店も近くにはなかったのでタオルで歯を磨いていました。

今年初めて参加しようとしている人、参加を迷っている人へ

GoogleI/Oは助け合いのコミュニティが強く、日本人のコミュニティもあります。
最もオープンなのは、Google I/O GDG Japanで、I/Oへの参加有無を問わずコミュニティに参加することが出来ます。
参加について迷っていることの相談や、旅程についてのアドバイスや、後述するルームシェアについてなどの情報もやり取りされるので、是非入ってください。

これから起きること

例年通りだと、次のような流れになります。
2月23日から申し込み開始。
例年は申し込みフォームは英語です。最近Googleは日本語訳を強化しているので、日本語に訳されている可能性もゼロではないです。
日本語訳が出てこなかったらこのサイトで訳を掲載するかもしれません。(確約できませんが・・・)

一週間程度で当確発表。
ここで当選した人の中でコミュニティーのフォローが欲しい人はGoogle I/O GDG Japanに参加できることを記載するか、個別にメッセージを下さい。

落ちた場合→敗者復活戦が行われる場合があります。

受かった場合

できるだけ早めにホテルと航空券を確保します。
特にホテルについてはマウンテンビューは宿泊施設の数が限られている上に、交通機関があまり発達していないため利便性の良い宿泊施設は少なく、激しい争奪戦になります。

航空券についても、サービスの良い成田−サンフランシスコ間を飛ぶANA運行便、羽田−サンフランシスコ間を飛ぶJAL運航便はどちらも格安チケットが売り切れるのが早いので、早めに確保しておいたほうが良いです。
ホテルや航空会社の選び方については後述します。

2月10日時点でやるべきこと。

申込みが2週間後、当確がわかるのはその後なので、具体的に今動けることは少ないですが、次の点を確認しておくといいです。
申込時にクレジットカードが必要になる可能性があるので、クレジットカードの有効期限を確認。現地で使うことを考えてVISAのカードが有るといいです。

当選すると、ホテル・航空券確保競争が始まるので、予め航空券と泊まるホテルに目星をつけておくと迷わなくていいと思います。
全てのホテルが埋まるということはないと思いますが、価格が安くて交通の便がいいホテルは早い段階で売り切れてしまう恐れがあります。
航空券を取る時にパスポートの番号が必要だったりするのでこの時までにパスポートも取っておいたほうが良いです。

ホテルについて


マウンテンビュー付近については大型のホテルが少なく、しかも価格が高騰気味です。
サンフランシスコから離れることで状況は改善するかと思っていたのですが、残念ながら逆にサンフランシスコのホテル代が安くなっていて価格的メリットは逆転しつつあります。
更に問題は、一昨年までのモスコーニセンターと違ってI/O会場から徒歩圏内に宿泊施設がほぼありません。
また会場自体公共交通機関が接続しておらず、Uberやレンタカーなどを使って自分で移動手段を確保するのでなければ、Googleの用意するシャトルバス頼みになります。
シャトルバスがどこを運行するかについてはまだ情報が出ていませんが、参考までに去年の情報をシェアします。

なお、去年はサンフランシスコ市街地からもシャトルバスが出たそうですが、渋滞に阻まれ時間的に厳しいものがあったそうなので、素直にマウンテンビュー付近のホテルを取ることをおすすめします。
agodaやExpediaであれば日本からも宿を取りやすいです。

ホテルについては、複数人でルームシェアすることで価格を下げられる場合があります。
アメリカのホテルは宿泊客の上限が決まっていてその範囲なら何人泊まっても同料金とか、ベッド代を追加するだけで泊まれたりするので宿泊費を劇的に下げることが出来ます。
まともなホテルに一人で泊まろうとすると10万円近い金額になるので、仮に二人でシェアすれば5万円、3人でシェアすれば7万円近く旅費が浮きます。
このあたりのルームシェア相手についても上記のSNSなどで情報交換されるので、チェックしておくことをおすすめします。

私は去年初めて一人部屋を取りました。価格的にはきつかったですが、時差ボケで寝付けない時には仕事に打ち込めるなどやはり気楽さは感じました。
去年取ったホテルはaloft santa clala。ホテルは綺麗だったのですが、風呂はガラス張りで玄関から見えるし、その前にあるトイレは扉すらない(一応寝室からは壁があるが)状態でルームシェアしていたらかなり気まずかっただろうと思います。

飛行機について


飛行機については、自分が住んでいる地域によっても変わりますが、日本からサンフランシスコへの直行便が飛んでいるのは羽田・成田・関空の3空港。また、成田からはサンノゼへの直行便も飛んでいます。
海外の経由地も込にすると選択肢は更に広がります。
ロサンゼルス経由は本数も多く取りやすくなりますし、アジア経由の場合は価格も安いです。

飛行機については、ビジネスやファーストを取れる人は、(私は無理です)ともかく
エコノミーの場合、最短でも9時間近いフライトになるのでどの航空会社のどの機体に乗るかが意外と重要だったりします。

Google Flightを元にした航空会社のサービス一覧は次の通り
凡例
HND:羽田空港
KIX:関西国際空港
NRT:成田
SFO:サンフランシスコ空港
SJC:サンノゼ空港
B777:おっきい飛行機
B747:すごくおっきい飛行機 古い
B787:ちゅうくらい飛行機 新しい
A350:ちゅうくらい飛行機 新しい
会社と機体シート電源USB給電WiFiシートスクリーンシートピッチ
全日空 B777(NRT-SFO)86cm
全日空 B787(NRT-SJC)-81cm
日本航空 B777(HND-SFO)86cm
United B747 (NRT-SFO)--79cm
United B787 (KIX or HND-SFO)81cm
アシアナ B777 (ソウル-SFO)-84cm
エバー航空 B777(台北-SFO)79cm
チャイナエアライン A350(台北-SFO)81cm
エアチャイナ B747 (北京-SFO)-81cm
大韓航空 B747(ソウル-SFO)-84cm
シンガポール航空 B777(香港-SFO)-81cm
※サービスの詳細については変わることが有ります。最終的には航空会社に確認してください。

Unitedの747についてはタブレットやスマートフォンを持参すると映像配信が行われるそうです。

飛行機についてはやはり設計が新しいB787やA350が揺れにくいようです。代わりに大型のB777はシートが広めに取られる傾向にあるみたい。
B747については、この中で唯一の4発エンジンということもあって騒音面ではかなり不利。設計が古い分よく揺れるので、そういうのが苦手な人はおすすめしないです。

なお、殆どの航空会社が格安チケットはキャンセル不可ですが、United航空に関しては条件付きながら、2万円程度の手数料を引かれて別の航空券の購入チケットに割り当てられたり、同行者の死亡時や本人が病気になったときはキャンセルが可能な場合があるなど幅広くキャンセルが認められています。(詳しいキャンセルポリシーについてはUnited航空に直接お問い合わせください)
United航空とANAは相互にコードシェアしているので、United航空でANA便を予約する事もできます。
注意点として、去年はUnitedのサイトでANA便を予約したのですが、座席指定や事前チェックインができないなどの制約もありました。
Viewing all 342 articles
Browse latest View live