UIの基礎

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

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

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

Unable to build: the file dx.jar was not loaded from the SDK folder!

環境はMacOSX / Eclipse3.6 。新しいプロジェクトでタイトルのエラーが出てコンパイルできない問題が。

 

結論としては、Android SDK Managerを起動して、環境設定からキャッシュをクリアしたら、Android SDK Tools Ver21が正常にアップデート出来るようになりました。(それまでどうやってもVer20までしか出て来なかった)

http://stackoverflow.com/questions/13392617/in-eclipse-android-4-2-unable-to-build-the-file-dx-jar-was-not-loaded-from-the

先人に感謝。

iPhone5とその周辺

iPhone5をあまり悩まず予約しました。

機種変更自体はすんなり決めたのですが、悩んだのはキャリア。
今のメインキャリアはSoftbankなのですが、auはテザリングできるんですよね。
仕事柄・趣味柄どうしても持っている端末が多くなるので、
できるだけ持ち運ぶ端末は減らしたいところ。
auにNMPすればテザリング用端末を1つ減らすことができるので大変助かります。

と、思ったのですが、結局予約したのはSoftbankでした。
メールアドレス(未だvodafone)が変わることの周知やNMPの予約番号のことを考えるとなんだか面倒で。テザリングだけなら今の通信環境でもできてますし。
というわけで、あと2年はSoftbankの売上に貢献することになりそうです。

iPhone5と同時にiPodNanoとiPodTouchが更新されました。
iPhone5はリークされまくっていたので、まあ予想通り・予定通りでしたが、
iPodTouchはかなり良くなりましたね。もう3G/LTEの無いiPhoneということで、
Wifiルーターを持っている人にはいいと思います。

そして、iPhone5の周りの反応を見て思うのは、Appleもすっかりコモディティ化したな、ということ。

かつてのAppleはデザイナーか、わざわざ苦労を買ってまで面白い機械を触るギークくらいしか使わないニッチなコンピューターだったのに、今や勉強会に行ってもMac率は確実に5割を超えるような勢い、iPhoneに至っては、電車の車両内の7割くらいの人がiPhoneだったりします。Appleを持つことがステータスではなく、生活の一部になりました。

まあ何を言いたいのかというと、

「Apple製品のAppleロゴがうざく感じてきた」

ということ。なんでだろうなあ。会社のディスプレイはDellだらけだけど、そうは感じないのに。

[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] なんて言われます。←検索用

ActionBarSherlockでNoClassDefFoundError(ただしGingerBread以下)

あるアプリケーションを作っていて、UIをActionBarで統一するためActionBarSherlockを導入しました。

ListView関連サポートがないとか(これはなんとか回避)、MapActivityサポートがないとか(これも無理矢理回避)困難を極めたのですが、普通に実装しているのにNoClassDefFoundErrorが出る事案が発生。

それまでGalaxy Nexusで動かしていたときは何とも無かったのに、NexusOneで急に出るようになってしまいました。これがAndroidの互換性の罠か…。

調査したところ、SearchViewをContexual Menuとして実装するところを外すと上手くいきました。
NoClassDefFoundErrorが何故出るかは不明なのですが、よくMapViewでGoogleAPIsを指定しないと同じような事象になるので、まあそういうもんだろうとあまり考えずに それっぽい実装をして終了。こんな記事では役に立たないこと請け合いのなので、ダメそうだった部分を記載しておきます。

 

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	MenuInflater inflater = this.getSupportMenuInflater();
	inflater.inflate(R.menu.contexual, menu);
	SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
	〜〜〜〜〜〜

ArtIME バージョンアップ (v1.3)

前回のアップデートから半年経ってしまいましたが、ようやくバグを取りきり、アップデートを掛けました。

ダラダラ書かせていただくと、今回のアップデートはちょっとしたバグを取るために正攻法で挑んだため、アプリサイズが倍になってしまうという状態になっています。
元々のバグというのは、AndroidのOS側に起因した、

「キーリピートされている状態でキーボードの変更が起きるとリピートが解除されない」

というもので、Androidで日本語IMEを開発されている方には有名なバグのようです。
動作としては、「未変換状態の日本語を2文字以上入力し、デリートボタンを押し続けると、2文字以降はキーリピートがかかるが、入力領域の最後の1文字を削除する直前でKeyboardView側のKeyboardが入れ替わり、その入れ替わりのタイミングでキーリピートが解除されない」事象が発生します。

正攻法で、と言ったのは、結局このバグを取るためにAndroid側のソースをForkして、修正して取り込んだためです。 このために、周辺のリソースをも巻き込んだ膨大な修正をせねばならず、結果サイズが増えました。本来はそのキーリピートの部分だけ上手く回避して実装する方法もあるのですが、今後の拡張性を考えて、Android側のソースをプロジェジェクト側に持っておいたほうが良い、という判断を最終的にしています。

今後のArtIMEですが、できるだけOpenWnnのソースを残すように拡張していたのですが、ここで思い切ってソースを綺麗に書き換えようと思っています。当然スピードも早くなりますし、メンテンナンス性も向上することが見込まれます。また、複数あるビジュアルテーマも統合し、プラグイン化して外出ししようと思っています。ArtIMEの次のバージョンにご期待ください。