2011-06-29 [長年日記]
Androidアプリを3.0に対応させる方法
Android端末のバージョン毎のシェアをみるかぎり、現状ではAndroid3.0以降に対応する動機は薄いと言わざるを得ないけど*1、将来的なものを見据えて対応する場合にどうすればいいのかという話。あるいはフォトマップをリリースしてみての反省会。
最低限何をすればいいか
基本的には何もしなくてもOK。動作はする。ただし、1.x系との共存は難しそう*2。2.x系であればまっとうな作りをしているアプリならそれなりの見た目になる。具体的にどのアプリとは言わないけれど画面サイズをスマートフォンの範囲で決め打ちして作っていると、画像が横にだけ引き伸ばされて悲惨なことになったりする。2.xでも7inchタブレットサイズの端末というのもあるわけだし、HTMLでいうところのリキッドレイアウト的な考え方で作ったほうがいいだろう。
既存のアプリを3.x対応にする
2.x,3.xでそれぞれそれなりの見た目で表示させるには少し手を入れる必要がある。アプリが2.xで問題なく動作している前提で、
- プロジェクトのTargetのAPIを11以上にする。いまなら12にすればOK。
- ManifestでminSdkVersionとtargetSdkVersionを設定する。
- Android2.1からの対応ならminSdkVersionは7で、targetSdkVersionは先ほど選んだプロジェクトのTargetAPIと同じにする。
- テーマとして、@android:styles/Holo.*を指定する。
これで、3.xでは「Holographic」な表示になり、2.xでは対応する従来のテーマが適用される。ただし、テーマの対応が一対一ではないのと、オブジェクト全てに想定通りの設定がなされるかというとそうでもないため、res/values以下に従来のテーマを指定したスタイルを配置、res/values-v11以下に3.xのテーマを指定したスタイルを配置してそれぞれカスタマイズするという方が汎用性もあっていい。
新規あるいは機能追加で2.x,3.x両対応にする
先程の項目は全てやっている前提で、例えばメニュー*3の特定のアイコンは常に表示させたいだとか、ある場面ではActionBarを消したいだとか3.x固有の動作をさせたくなってくると思うのだけど、その時には、try{}catch{}節で
try{ 3.x系の操作 } catch(NoSuchMethodError e){ 2.x系の同等の操作 or なにもしない }
といった感じでエラーをハンドリングする必要がある。
また、同じAPIでも挙動が異なる場合があるため最終的にはエミュレータ、実機で動作を確認したほうがいい。 さらに3.xでは複数のインテントを位置画面上に表示するfragmentなる機能があるらしいのだけど、それはまたそのうち。