Moto360を手に入れ、そして手放した話。

以前からAndroid Wear は気になっていたのですが、Moto360の円形ディスプレイに惚れて、入手するまでずっと我慢していました。
だが、9月の中旬にようやく個人輸入で手に入れることができたにもかかわらず、開封して30分で手放そうと決め、そして今もう既に手元にはありません。今日はその話を。

勘違いしてほしくないのは、Moto360は間違いなく今までの腕時計型ガジェットの中で最高峰だと私は思っています。Androidとの連携もスムースだったし、操作に迷うこともなく、美しいディスプレイや革バンドに至るまで良く出来ています。

ただ、私は、思ったよりも「腕時計」にこだわりがあったようで、持ち上げただけで即座に時間が確認できる腕時計に比べて、加速度で認識するとはいえMoto360は腕を上げてからディスプレイが点灯するまでのコンマ数秒にフラストレーションを感じました。どんなに、これは腕時計ではなくガジェットだ、と頭のなかでは意識しても、どうしてもこの差は埋まりませんでした。スマートフォンの通知を転送してくれるのも楽かもしれませんが、日常的にそれほど通知を気にすることも実はなく、結局のところMoto360で新しい体験はできるかもしれないが、私の日常を良い方向に上書きするほどではなかった、と気がついたのでした。

この差は多分電子書籍リーダーの体験と同じで、私自身一度は電子書籍にトライしたものの紙の本に戻ってます。生まれてから紙の書籍を体験していなければ違和感を感じないものの、紙の本の経験が長かったのでその経験を上書きできないのです。電子書籍だと読む喜びや残る知識が半減してしまい、最近は実用書でも本で買うようにしています。
(面白いのは、マンガだと電子書籍自体に全く違和感はないのです。読んだあとの余韻も変わりません。体験の違いから来るのかもしれないですが。)

話を戻すと、
結論として、少なくともスマートフォンとの連携無しで稼働するようになるまでは、腕時計型ガジェットには手を出さないことにしました。エンジニアとして出遅れるかもしれないが、そのリソースは他に振り分けることにします。

最後にMoto360のファームアップデート前の起動アニメーションを。18秒くらいから始まるアニメーションがMoto360の開発コンセプトをよく表していると思います。

 

Google Maps Android API v2 の ズームレベルとは何を指すか

Google Mapsを取り込んだAndroidアプリを作っていた際に、

「画面の1/4程度を動かすとデータリロードさせたい」

という要望が上がりまして、その実現方法を検討したことがありました。

通常 Mapの移動については、MapオブジェクトにsetOnCameraChangeListenerを設定して、
カメラの移動を取ればよいのですが、取れるのはLatLonであり、そのときのMapのズームレベルによって「画面上どれだけ動いたか」が変わることになります。

そこで、LatLonとズームレベル・それから画面上の実移動についての相関をアバウトに取れる仕組みをアプリに入れました。そのロジックをご紹介します。

Google Maps Android APIではズームレベル自体は2〜21まで設定できるのですが、
ズームレベル2を設定した場合、Google Mapは世界地図の概ね1/4を表示していましたので、
実際には、0を起点とした下記のような仮説を立てました。

スマートフォンの画面に表示される地図の幅(Km)
= 地球の円周(Km) / (2 ^ ズームレベル )

つまり、地球の円周≒40075km とすると、
ズームレベル 2 の場合は 40075km / (2 ^ 2) = 約10018km
がスマートフォンの画面幅に合わせて表示されます。

逆に駅から徒歩10分の周辺を表示したい場合は、
徒歩所要時間 = 80m / 1分だとして、大体1.6km四方が見られれば良いので、

40075 / 2 ^ x = 1.6(km)
x ≒ 14.6

となり、ズームレベルは14.6が適切、ということになります。

 

Amazon EC2でMozc for Android(オープンソース版Google日本語入力)をコンパイルしてみる

IMEを作っている(そして放置している)ものとして、Google日本語入力が出た時点で「こっちでいいじゃん」的な気持ちになっていたのですが、とりあえずMozc for Android(オープンソース版Google日本語入力)でも弄ってみようと思ってはや1年近く。ようやく時間ができたので試してみました。それなりに悪戦苦闘しそうだと思ってはいたのですが、割とすんなりできたので手順を公開します。

本来の手順自体はこちらにあります。
https://code.google.com/p/mozc/wiki/AndroidBuildInstructions

まずはEC2でインスタンスを作ります。t1.microでは途中でCPUパワーが足りずにBuildが進まなくなるため、最初からm1.smallで設定したほうが良いでしょう。tokyoリージョンなのは趣味です。

スクリーンショット 2014-01-01 11.33.41

この時点でEBSを16GiBにしておく必要があります。これもデフォルトの8GiBではコンパイル中に容量が足りなくなるためです。
また、今のところUbuntuでないとコンパイルが保証されていないので、Ubuntu Server 12.04.3 LTS 64bitを選択してますが、後から32bitライブラリを足たりしているので、もしかしたら最初から32bitが良かったのかもしれません。

ログインしたらまず足りないものをインストール

% sudo apt-get install ant g++ make python subversion openjdk-6-jdk

Unzip / Subversion / make / gcc / pkg-config も入れておきます。

% sudo apt-get install unzip
% sudo apt-get install subversion
% sudo apt-get install make
% sudo apt-get install gcc
% sudo apt-get install pkg-config

32bitライブラリを入れておきます。

% sudo apt-get install ia32-libs

一度インストールしたら、

% sudo apt-get update

も実行してください。

AndroidSDKとAndroidNDKもダウンロードして展開。

% wget http://dl.google.com/android/adt/adt-bundle-linux-x86_64-20131030.zip
% wget http://dl.google.com/android/ndk/android-ndk-r9c-linux-x86_64.tar.bz2
% unzip adt-bundle-linux-x86_64-20131030.zip
% tar jxfv android-ndk-r9c-linux-x86_64.tar.bz2

いよいよコードをダウンロード

% cd ~/
% svn co http://src.chromium.org/svn/trunk/tools/depot_tools
% export PATH=”$PATH”:`pwd`/depot_tools
% mkdir -p ~/src/mozc
% cd ~/src/mozc
% gclient config http://mozc.googlecode.com/svn/trunk/src
% gclient sync

周辺ライブラリzinnia(手書き文字認識エンジン)が足りないのでダウンロード・インストールしておく

% cd ~/
% wget http://downloads.sourceforge.net/project/zinnia/zinnia/0.06/zinnia-0.06.tar.gz
% tar zxvf zinnia-0.06.tar.gz
% cd zinnia-0.06/
% ./configure
% make
% sudo make install

再度 gclient syncから

% cd ~/src/mozc
% gclient sync

パスを通す

% export PATH=~/android-ndk-r9c:~/adt-bundle-linux-x86_64-20131030/sdk/tools:~/adt-bundle-linux-x86_64-20131030/sdk/platform-tools:”$PATH”
% which ndk-build android adb

さらにJava をインストールし、SDKをアップデートしておきます

% sudo add-apt-repository ppa:webupd8team/java
% sudo apt-get update
% sudo apt-get install oracle-java7-installer
% android update sdk -u -t platform,tool,platform-tool,extra-android-support

コンパイルを開始します

% cd ~/src/mozc/src
% python build_mozc.py gyp –target_platform=Android

(WPでは見えませんが、target_platform の前のハイフンは2つです)

% python build_mozc.py build_tools -c Release
% python build_mozc.py build android/android.gyp:android_manifest

local.propertiesを作成

% android update project -s -p android –target android-17

そしてBuildします

% python build_mozc.py build android/android.gyp:apk -c Debug_Android

これでDebugバージョンのapkが
/home/ubuntu/src/mozc/src/android/bin/MozcForAndroid-debug.apk
に出来ます。

 

以下補足です。

エラーが出る場合 1:

make: *** [out_android/Debug_Android/obj/gen/data_manager/oss/system.dictionary] Error 137
make: *** Waiting for unfinished jobs….

こんな感じのエラーはCPUパワーが足りてません。
t1.microではCPUパワーが足らないので、m1.small以上で起動しなおしましょう。

エラーが出る場合 2:

BUILD FAILED
/home/ubuntu/src/mozc/src/android/custom_rules.xml:42: The following error occurred while executing this line:
/home/ubuntu/adt-bundle-linux-x86_64-20131030/sdk/tools/ant/build.xml:601: The following error occurred while executing this line:
/home/ubuntu/adt-bundle-linux-x86_64-20131030/sdk/tools/ant/build.xml:653: The following error occurred while executing this line:
/home/ubuntu/adt-bundle-linux-x86_64-20131030/sdk/tools/ant/build.xml:698: Execute failed: java.io.IOException: Cannot run program “/home/ubuntu/adt-bundle-linux-x86_64-20131030/sdk/build-tools/android-4.4/aapt” (in directory “/home/ubuntu/src/mozc/src/android/protobuf”): error=2, No such file or directory

これは32bitライブラリが足りていないときです。このコマンドからia32を導入してください。

% sudo apt-get install ia32-libs

エラーが出る場合 3:

INFO: Running: make -j2 MAKE_JOBS=2 BUILDTYPE=Debug_Android builddir_name=out_android apk
ACTION android_android_gyp_assets_touch_stat_data_target_assets_touch_stat_data android/dummy_touch_stat_data
make: *** [android/dummy_touch_stat_data] Error 1
Traceback (most recent call last):
File “build_mozc.py“, line 1437, in <module>
main()
File “build_mozc.py“, line 1425, in main
BuildMain(cmd_opts, cmd_args, original_directory_name)
File “build_mozc.py“, line 1038, in BuildMain
BuildOnLinux(options, targets, original_directory_name)
File “build_mozc.py“, line 992, in BuildOnLinux
RunOrDie([make_command] + build_args + target_names)
File “/home/ubuntu/src/mozc/src/build_tools/util.py”, line 97, in RunOrDie
‘==========’]))
build_tools.util.RunOrDieError:
==========
ERROR: make -j2 MAKE_JOBS=2 BUILDTYPE=Debug_Android builddir_name=out_android apk
==========

なんらかの理由でコンパイルが失敗しているので、一度cleanして実施すると上手くいく可能性があります。

% python build_mozc.py clean –target_platform=Android

エラーが出る場合 4:

/home/ubuntu/android-ndk-r9c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar: android/obj/local/armeabi/libclient.a: No space left on device

EBSボリュームが足りていません。EBSボリュームを拡張しましょう。詳しくは
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-expand-volume.html
でご確認ください。

さらに補足:
aaptのパスが通らなかった場合がありましたので、その場合は下記を投入してください。

% export PATH=/home/ubuntu/adt-bundle-linux-x86_64-20131030/sdk/build-tools/android-4.4/:”$PATH”

 

ArtIMEのセキュリティ状況について

ArtIMEはセキュアに利用することができます。以下ご確認ください。

・全ての入力情報をログに蓄積したり、サーバへ送信するなどは行っていません。
・学習した変換候補のみ、他のアプリから見えない形でローカルに保存されます。
・Social IMEをONにした場合のみ、変換候補を取得するため入力情報をSocial IMEに送信しています。これによるログ蓄積や収集は行っていません。
・Wikipedia検索及び辞書検索に切り替わっている場合は、簡易的な単語抽出を行ってWikipediaへ送信し、結果を表示します。これによるログ蓄積や収集は行っていません。

ご心配がある場合はご連絡戴ければ幸いです。

UIの基礎

どんなアプリもとりあえずこれは守ってほしい。

ユーザ
・ユーザは説明を読まない。可能な限り説明しないでも使える様にする。
・ユーザは慣れることは無い。小さなストレスは常に掛かり続ける。
・ユーザにできるだけ操作させない。メニューの階層を必要以上に深くしない。

配置
・同じ情報を扱うものはできるだけ近くに配置する。可能であれば同一化する。
ボタンを押すとボタン自身の表記が変わるなど。
・アフォーダンスを考慮する。
ボタンとして動作するものはボタンの形であることがユーザに取って重要。
・同一の動作をするものは別の場面でも同一の場所に配置する。
・違う動作をするパーツを他の場面で同一の箇所に配置しない。

[Android] Audio Focusで他のアプリの音を止める

http://developer.android.com/training/managing-audio/audio-focus.html

によれば、Audio Focusで他のアプリの音声がコントロールできるそうだ。

アプリに組み込んでみたが、onResumでrequestAudioFocusにAUDIOFOCUS_GAINしたら、、、

 

すごい!音が止まった!

 

相手はWinAmpでしたが、ピタっと音が止まってこちらの音が鳴る。素敵です。

サンプルソースはそのうち。

[Android] WebViewのonPageStartedでJavaScriptを挿入してはならない

某アプリを作成していてハマったことを。

Androidが標準的なブラウザをアプリの中に持つために、android.webkit.WebViewというものを用意しているのですが、addJavascriptInterfaceというJavaScript側からJavaを叩けるようになる便利なものがありまして、これを使っていろいろ試していました。

publicvoid onPageStarted(WebView view, String url, Bitmap favicon) {
    view.loadUrl(jsString);
}

こんな感じでonPageStartedでJavaScriptを挿入したのですが、これがどうも上手く動かない。
いろいろ試して分かったのは、
「onPageStartedでJavaScriptを挿入した場合、 HTMLのレンダリングとJavaScriptの解釈が同時に走り、JavaScriptの値をHTMLに反映できない」
らしいのです。
結局はonPageFinishedで入れ込んだあと、JavaScript側で処理を行なって事なきを得ましたが、
これってハマる人が多そうな気がします。WebViewの挙動にはくれぐれもお気をつけて。

C2DMで嵌りまくる

C2DMは便利なのですが、間にサーバをかませるのでトラブった時に原因追求が難しいです。
というわけでハマった点2点。

・C2DM は端末もGoogleアカウントを持っていないと通知が来ない。

まあ当たり前ちゃあ当たり前なんですが。試験端末に通知が来ないのでどうしたかと。

・Android3.1以上の端末ではアプリケーションを強制停止してしまうとC2DMが受け取れない。

こっちのほうが問題。日本語での解説が見つかりませんでしたが、確かにGalaxy Nexusではアプリのプロセスが起動していないと通知が来ません。
http://stackoverflow.com/questions/7433129/c2dm-reciver-doesnt-work-when-app-has-been-killed

broadcast intent callback: result=CANCELLED forIntent
Receiver package not found, unregister application [package] なんて言われます。←検索用

仙台へ

高校時代の3年間を同じ部活で過ごした友人が、19年を経て仙台でAndroid関連の団体の代表となったとのことで繋がりが出来、夏休みを利用して訪問させていただきました。

Fandroid
http://fandroid-ej.org/

通常はそこでブレストカフェというのを行っているようですが、そこで1時間ほどお時間をいただきまして、講演させていただきました。

普段では、震災による東北の経済の停滞からどのように発展をしていくか、というテーマを持って活動をされております。

その後、夕食にホヤなどを頂いたあと、一泊してその後松島など県内を回りました。

震災から5ヶ月経ちましたが、少なくとも車での移動では不自由することはなく、どこに行っても現地の人は本当に元気な様子でした。

ただ、道路脇のがれきがよく見ると車と船の残骸だったり、いくつかの建物の1階部分が空洞になっているのを見て、今回の災害の大きさを感じました。

支援と呼ぶには微々たるものですが、できるだけ現地でお金を落とすようにして、また来ようと心に誓いつつ帰りの新幹線に乗りました。

復興はまだ時間がかかると思いますが、東北のパワーを見て、私もできることを続けようと感じた2日間でした。