アプリケーションを様々スクリーンでテストする方法

様々なスクリーンをサポートするアプリケーションを公開する前に、全てのターゲットスクリーンサイズ、ピクセル密度でテストを行うべきです。プラットフォームの互換機能、またはアプリケーションに含まれる、スクリーン指定UIリソースによってどの様に表示されるかテストする事が出来ます。AndroidSDKは全てのスクリーンについてテストするツールを含んでいます。

アプリケーションのテスト環境として、サポートしたいスクリーンサイズ、ピクセル密度をエミュレートするAVDをそれぞれセットアップします。AndroidSDKは6種類のスキンを含んでいます。Android AVD Managerもしくはandroid toolを使って様々なスキンを使ってAVDを作る事ができます。また、様々なピクセル密度をテストする為にカスタムAVDをセットアップする事も出来ます。

Android SDKはテストに使える、デフォルトエミュレータスキンをいくつか提供します。これらのスキンはAndroidプラットフォームの一部として含まれています。Android1.6は以下のデフォルトスキンを提供します。

  • QVGA(240*320,low,small)
  • HVGA(320*480,medium,normal)
  • WVGA800(480*800,high,normal)
  • WVGA854(480*854,high,normal)

Android2.0ではさらに以下のデフォルトスキンを提供します。

  • WQVGA400(240*400,low,normal)
  • WGVGA432(240*432,low,normal)

コマンドラインでAVDを作る場合、以下の様にしてスキンを選択します。

android create avd … –skin WVGA800

また、実際のデバイスと物理的に同じサイズで実行される様にセットアップしたエミュレータでテストする事を推奨します。これによって、様々な解像度、密度における結果を比較しやすくなります。これをするには、あなたのPCモニタの凡そのピクセル密度をdpiで知る必要があります。(例えばDELLの30インチモニタの密度は凡そ96dpiです。)。エミュレータを起動する際に、-scale オプションにあなたのPCモニタのdpiを設定してください。例えば以下の様にします。

emulator -avd  -scale 96dpi

ADTを介してEclipseで開発している場合、-scale 96dpiオプションを “Additional Emulator Command Line Options” 配下、「実行とデバックの構成」の「ターゲット」タブで設定する事が出来ます。

-scaleオプションを付けて起動すると、あなたのモニタとskinのdpiに基づいて、エミュレータ全体のサイズがスケーリングされるので注意して下さい。Android SDKに含まれるデフォルトスキンについては以前のエントリを参照してください。

また、一つのサイズ、密度構成で異なる物理スクリーンサイズでテストする事も忘れないでください。例えば、30インチのモニターでこのスクリーン構成で表示させる為に、-scaleオプションに渡される値を96×2.8÷3.3=81dpiに調整しなければなりません。尚、-scaleオプションにスケーリング倍率を浮動小数点数で渡す事もできます。

emulator -avd  -scale 0.6

もし、デフォルトスキン以外のスクリーンでテストしたい場合は、デフォルトスキンを調整するか、カスタム解像度やピクセル密度でAVDを作る事ができます。

AVD ManagerのCreate New AVDダイアログで、カスタムスキン解像度、ピクセル密度を指定する事が出来ます。

avd-density

コマンドラインでは以下の様なステップでカスタムAVDを作成出来ます。

1.create avdコマンドで新しいAVDを作ります。この時、–skinオプションでデフォルトスキン名(例えば、WVGA800など)か、カスタムスキン解像度を指定します。

android create avd -n 【name】 -t 【targetID】 –skin WVGA800

2.新しいAVD向けにカスタムハードウェアプロファイルを作るか聞かれたら”YES”と答えます。
3.いくつかの項目を設定して行きます。Abstracted LCD densityと聞かれたら、low密度スクリーンなら”120”、mediumなら”160”、highなら”240”と入力します。
4.その他の設定をして、AVDを作成します。

上記の例では、新しいAVDは5.8インチのWVGAスクリーンをエミュレートします。

エミュレータスキン構成を調整するもう一つの方法として、デフォルトスキンを使い、-dpi-deviceオプションを起動時に設定する事も出来ます。

emulator -avd WVGA800 -scale 96dpi -dpi-device 160

androidドキュメント和約「様々なスクリーンのサポートについて」その1
androidドキュメント和約「様々なスクリーンのサポートについて」その2
androidドキュメント和約「様々なスクリーンのサポートについて」その3
androidドキュメント和約「様々なスクリーンのサポートについて」その4
androidドキュメント和約「様々なスクリーンのサポートについて」その5
androidドキュメント和約「様々なスクリーンのサポートについて」その6
androidドキュメント和約「様々なスクリーンのサポートについて」その7
androidドキュメント和約「様々なスクリーンのサポートについて」その8

 

レガシーアプリケーション対策について

もしあなたがAndroid1.5以前向けのアプリを開発して公開している場合、どの様に適合させるか検討する必要があります。何故なら、そのアプリはandroid1.5以前の端末にも、様々なサイズ、解像度のスクリーンに対応した新しい端末達にもインストールできるからです。

新しい端末および様々なスクリーンをサポートする為には、アプリにいくつかの改修が必要ですが、安定したアプリへの改修は極力少なくしたいでしょう。様々なスクリーンを持つ新しいデバイスと、既存の端末に対応させる為に、あなたのアプリを拡張する方法はいくつもあります。あなたのアプリケーションにこれらの変更を実施し、全ての端末に一つの.apkで対応する事が可能なはずです。

推奨される対策は、最新のプラットフォーム向けに開発を行い、最古のプラットフォームで試験を行う事です。いかが実施方法です。

1.互換性を維持する為にandroid:minSdkVersion属性はそのままにしておきます。新しい端末や、様々なスクリーンに対応する為に、この値を増加させる必要はありません。
2.uses-sdk要素に、android:targetSdkVersionと言う新しい属性を追加する事で互換性を拡張します。この属性に"4"を設定します。これにより、技術的には旧バージョンのAPIを使いながらも、新プラットフォームのマルチスクリーンサポートを継承できます。
3.空の<supports-screens>要素を<manifest>の子要素として追加します。もしサイズや密度の属性を有効にする必要があるなら、ここにそれらを追加します。
4.android1.5以前向けから、android1.6以上向けにビルドプロパティーを変更して下さい。新しいマニフェスト属性のせいで、古いプラットフォーム向けにはアプリケーションのコンパイルが出来なくなります。
5.AVDをandroid1.6以上でテストできるようにセットアップします。あなたがサポートしたスクリーンサイズ、密度のAVDを作成します。AVDを作成したら、実行するシステムイメージとしてandroid1.6以上のプラットフォームを選択する様にしてください。更に詳しくはHow to Test Your Application on Multiple Screensを参照してください。
6.AVDをandroid1.5向けにテスト出来る様にセットアップします。AVDをあなたがターゲットとしたい古いプラットフォームを稼働させる事で、互換性の試験及び、機能先祖がえりが無い事の確認が可能です。
7.アプリケーションをandroid1.6向けにコンパイルし、作成したAVD上で起動します。あなたのアプリケーションの挙動と見た目を観察し、全てのユーザー操作を検証します。
8.全ての表示や機能の問題をデバッグします。アプリのコード内で解決する問題について、<strong>API Level4以上で導入されたAPIを使わない事</strong>。
9.リソース関連の問題については、以下の様な解決方法があります。
 ・<supports-screens>にanyDensity="false"をセットし、密度互換スケーリングを有効にします。
 ・必要とする全てのサイズ、密度指定リソースを作成し、適切な識別子でタグ付けされたディレクトリに配置します。
 ・このドキュメントにリストアップされた何れかのリソース識別子によってタグ付けされたサイズ、密度指定リソースディレクトリを追加する場合、それらのディレクトリーにv<api-level>識別子(例えば、-v4)を付ける事を忘れないでください。これにより、それらのリソースがandroid1.5以前のプラットフォームで実行された時に無視されるようになります。

10.もし、largeスクリーンをサポートせず、スクリーン互換モードで表示させたい場合、largeScreen="false"属性をマニフェストの<supports-screens>要素に追加します。
11.もし、smallスクリーンをサポートせず、AndroidMarketにてsmallスクリーン端末にアプリを提供したくない場合、smallScreen="false"属性をマニフェストの<supports-screens>要素に追加します。
12.サポートしたい全てのスクリーンサイズとプラットフォームで想定通り稼働するまでテストとデバッグを繰り返します。
13.Export、zipalign、そして以前のバージョンと同じキーで署名し、アップデートしてユーザに公開します。

特に、アプリケーションをsmall-screenデバイスのAVDでテストする事を忘れないでください。QVGA・low密度のスクリーンを持つ端末が出てきています。これらの端末のユーザはあなたのアプリケーションをダウンロードしたいかもしれませんので、あなたはアプリがsmallスクリーン端末でどんな見え方で機能するのか理解しておく必要があります。多くの場合、それらの端末向けにはスクリーンエリアと密度の減少により、デザイン、コンテンツ、機能において妥協が必要になります。

androidドキュメント和約「様々なスクリーンのサポートについて」その1
androidドキュメント和約「様々なスクリーンのサポートについて」その2
androidドキュメント和約「様々なスクリーンのサポートについて」その3
androidドキュメント和約「様々なスクリーンのサポートについて」その4
androidドキュメント和約「様々なスクリーンのサポートについて」その5
androidドキュメント和約「様々なスクリーンのサポートについて」その6
androidドキュメント和約「様々なスクリーンのサポートについて」その7
androidドキュメント和約「様々なスクリーンのサポートについて」その8

 

スクリーン独立のベストプラクティス

複数スクリーンサポートの目的は、どんなディスプレイでも実行出来て、どんなスクリーン仕様でも適切にきのうするアプリケーションを作る事です。

あなたはこれを簡単に実現できます。以下にクイックチェックリストがあります。

1.XMLレイアウトファイルにて、pixではなくdipを使う。
2.AbsoluteLayoutを使わない。
3.固定pixel値でコーディングしない。
4.ピクセル密度、および/もしくは、解像度特定のリソースを使う。

1.XMLレイアウトファイルにて、pixではなくdipを使う。
XMLレイアウトファイルで、layout_width,layout_heightを定義する際に、wrap_content,fill_parentもしくはdipを使う事で、そのスクリーンに適切なサイズで表示される事が保証されます。例えば、layout_width=”100dip”と設定されたあるViewは、HVGAの160dpiスクリーンでは100pixel、WVGAの240dpiスクリーンでは150pixelと計測されますが、物理的なサイズはほぼ同じになります。

2.AbsoluteLayoutを使わない。
AbsoluteLayoutはAndroid UI ツールキットによって提供されるレイアウトコンテナの一つです。他のレイアウトと異なり、AbsoluteLayoutは複数ディスプレイ対応に適さない、位置固定利用を義務付けています。したがって、AbsoluteLayoutはandroid1.5の頃に推奨されていました。

FrameLayoutを使ったり、子ビューにlayout_marginを設定する事で、殆ど同じ事が実現できます。この方法の方が、より柔軟で、複数スクリーン対応に適しています。

3.固定pixel値でコーディングしない。

パフォーマンス維持、およびコードをシンプルにする目的で、Android framework APIは寸法や座標を表現するのにpixelを基本単位として使用します。つまり、Viewの寸法は常にpixelコードで表現されているわけです。例えば、myView.getWidth()が10を返した場合、そのビューの幅は10pixelです。コードの中で、pixel値をスケールさせる必要がある事が良くあります。更に詳しくは以下を参照して下さい。

dipからpixelへの変換

座標をdipで表現して、後からpixelに変換しないと行けない事が良くあります。ユーザーが16pixel以上指を動かしたらスクロールジェスチャーを認識するアプリを想像してください。基本スクリーンでは、ユーザは16pixel/160dpi=2.5mm以上指を動かさないとスクロールさせられません。240dpiのhigh密度ディスプレイの場合は、16pixel/240dpi=1.7mmとなり、よりセンシティブなUIとなります。これを是正する為に、ジェスチャーの閾値はdipで表現し、後から具体的なpixel値に変換する必要があります。

// The gesture threshold expressed in dip
private static final float GESTURE_THRESHOLD_DIP = 16.0f;

// Convert the dips to pixels
final float scale = getContext().getResources().getDisplayMetrics().density;
mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels

android.util.DisplayMetrics.densityフィールドはスクリーンの密度に合わせてdipをpixelに変換する際に使う、スケール係数を特定します。カレントスクリーンのmetricsにはContextか、Activityを経由してアクセスする事ができます。medium(160dpi)密度のスクリーンでは、DisplayMetrics.densityは”1.0″となり、high(240dpi)では”1.5″となります。詳しくはDisplayMetricsクラスのドキュメントを参照して下さい。

事前リサイズ設定値を使う
ViewConfigurationクラスはandroid frameworkで使われる、殆どの共通な距離、速度、時間にアクセスする事ができます。例えば、frameworkでスクロール閾値として使用されるpixelで表現された距離は以下で得られます。

ViewConfiguration.get(aContext).getScaledTouchSlop()

getScaledプリフィックスで始まるメソッドはカレントスクリーンの密度にかかわらず、適切に表示されるpixel値を返す事が保証されています。

4.は次回書きます。。。

androidドキュメント和約「様々なスクリーンのサポートについて」その1
androidドキュメント和約「様々なスクリーンのサポートについて」その2
androidドキュメント和約「様々なスクリーンのサポートについて」その3
androidドキュメント和約「様々なスクリーンのサポートについて」その4
androidドキュメント和約「様々なスクリーンのサポートについて」その5
androidドキュメント和約「様々なスクリーンのサポートについて」その6
androidドキュメント和約「様々なスクリーンのサポートについて」その7
androidドキュメント和約「様々なスクリーンのサポートについて」その8

 

facebookのビジネス活用について

On 2010年10月5日, in ブログ, by cliph

最近、facebookにはまりつつある。

もちろん、Twitterもやっているが、どちらかと言うと外出中にモバイルでつぶやく事が多く、
PCに向かってガッツリやるのはfacebookと言う住み分けが、私の中に構築されつつある。

これは、twitterの手軽さ、シンプルさと、facebookの高機能、奥の深さを反映した結果だろう。

では、「mixi」と「facebook」だったらどっちを使っているかと言うと、私は圧倒的にfacebookだったりする。

もともと私はmixiにはまりきることが出来ず、ここ数年放置していた人間なので当然の結果だと思うが、では、何故facebookなら行けるのかと言うと、これはオープンな実名文化が根付いているからだろう。

ソーシャルメディアに求めるものは人それぞれだ。身内とのコミュニケーションや、匿名での忌憚無いコミュニケーションを楽しみたい人もいるだろうし、ソーシャルゲーム等を楽しみたい人もいるだろう。そういうニーズであれば、やっぱりmixiが適しているんだと思う。

でも、私はその辺にはあまり興味がない。

最近の私が求めるのはどちらかと言うと、ビジネスに活かせる情報収集、人脈拡大だったりするので、そう言った観点で使うのであれば、間違いなくmixiよりfacebookが適している。なぜなら、信頼できる情報も、人脈も、実名でなければ得られないものだからだ。

そもそも、mixi上でビジネスライクな活動をするのは、何だかそぐわない気がしますよね?多分、それはmixiが楽しむ文化だからなんでしょう。それに引き換え、facebookはビジネスを含めた全ての活動を許容する文化があるように思う。

何だか、取り留めの無い文章になってしまったが、要するに、ビジネス上の情報収集、人脈構築にはTwitterでもmixiでも無く、facebookが適しているんだ。と言う事を実感したわけです。

なので、皆さんもfacebookを使ったことが無ければ、そろそろ使ってみて下さい。

 

dialogへのlistview表示

On 2010年10月5日, in ブログ, by cliph

うーん。ハマった。

dialogに自作listiviewを設定しようとすると、
null pointer exceptionが発生してしまう。。。

普通にActivityに直接設定するのはできるのに、
dialogへの設定が出来ないのはなぜ?

しかも、
レイアウトXMLを使わずにコードでレイアウトを生成したら、
基本のArrayAdapterは出来た。

でも、GetViewをオーバーライドした自作adapterではやっぱりnull pointer exception。。。。

ダメだ。
今日はお手上げ。。。

 

スクリーンサイズおよびピクセル密度を表すリソースディレクトリ識別子について

androidはスクリーンの特性に合ったリソースを選択する為のリソースディレクトリ識別子をサポートします。これらの識別子を使って、サイズ、密度を特定したリソースをあなたのアプリケーションので提供出来ます。更に詳しい情報は以前に掲載した記事を参照して下さい。

resource_qualifier

ピクセル密度とスクリーンサイズは独立したパラメータで、システムにも個別に解釈されます。例えば、WVGA/高密度スクリーンはnomalスクリーンと解釈されます。何故なら、物理サイズがT-Mobile G1とだいたい同じだからです。一方、WVGA/mediumスクリーンはlargeスクリーンと解釈されます。(同じ解像度でより低い密度を提供する。つまり、物理的に基本スクリーンよりも大きいし、nomalスクリーンサイズよりもとても多くの情報を表示されると言う事です。)

lowとhighの密度をサポートし、異なるレイアウトを利用するアプリケーションのリソースディレクトリ構造サンプルを示します。

res/layout/my_layout.xml // layout for normal screen size
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-large-land/my_layout.xml // layout for large screen size in landscape mode

res/drawable-ldpi/my_icon.png // icon image for low density
res/drawable-mdpi/dpi/my_icon.png // icon for medium density
res/drawable-hdpi/my_icon.png // icon image for high density

res/drawable-nodpi/composite.xml // density independent resource

更に詳しい情報はAlternative Resourcesを読んで下さい。

androidドキュメント和約「様々なスクリーンのサポートについて」その1
androidドキュメント和約「様々なスクリーンのサポートについて」その2
androidドキュメント和約「様々なスクリーンのサポートについて」その3
androidドキュメント和約「様々なスクリーンのサポートについて」その4
androidドキュメント和約「様々なスクリーンのサポートについて」その5
androidドキュメント和約「様々なスクリーンのサポートについて」その6
androidドキュメント和約「様々なスクリーンのサポートについて」その7
androidドキュメント和約「様々なスクリーンのサポートについて」その8

 

ピクセル密度の独立

ピクセル密度を独立させることの目的は、アプリケーションが異なる密度のスクリーンに表示された時にに、ユーザーから見たUI要素の物理的なサイズを維持する事です。ピクセル密度の独立はレイアウトと、画像(アイコン等)両方に適用されます。ピクセル密度独立を維持する事は重要です。何故なら、高さや幅がピクセルで定義されているボタン等のUIエレメントは密度の低いスクリーンでは大きく、密度の高いスクリーンでは小さく表示されてしまうからです。この様な密度に依存したサイズ変更はアプリケーションのレイアウト、ユーザビリティー、他のアプリケーションとの安定性に悪い影響を及ぼす可能性があります。

プラットフォームはデフォルトでピクセル密度の独立を提供します。これは以下の3つの方法によります。

  • 画像リソースの事前リサイズ(リソースのロード時にリサイズされます。)
  • レイアウトに使われるDensity-Independent-pixel(dip)値の自動リサイズ
  • アプリケーションで使われる絶対的なpixel値の自動リサイズ(マニフェストでandroid:anyDensity=”false”に設定されていて、必要な場合のみ)

以下のサンプルスクリーンはプラットフォームによって提供される、ピクセル密度の独立によって提供されています。レイアウトと、ランチャーアイコンがスクリーンサイズ、縦横比、ピクセル密度が異なるのに、同じ物理サイズで表示されている事に注目して下さい。

dip
図1.左からWVGA high密度、HVGA medium密度、QVGA low密度

殆どのケースで、単純に全てのレイアウトをピクセル密度独立pixel(dipもしくはdp)またはサイズ独立pixel(sipもしくはsp)で特定する様に気をつけるだけで、あなたのアプリケーションにおいてピクセル密度独立のメリットを享受できるでしょう。もし、あなたが絶対的なpixel値を使用していて、マニュフェストにandroid:anyDensity=”true”と設定している場合は、pixel値をリサイズする必要があります。詳しくはConverting from dips to pixelsを参照して下さい。

スクリーンサポートに関するマニュフェスト属性

android1.6は新しいマニュフェスト属性を導入しました。この属性は下表の通り、異なるクラスのスクリーンへのアプリケーションの表示をコントロールするのに使います。smallScreens,normalScreens,largeScreens属性が以前の掲載した、表の標準化スクリーンサイズに一致します。

supports-screens

一般に、スクリーンサイズ属性を”true”にした場合、プラットフォームに対して、アプリケーションが全てのスクリーンサイズにについて、プラットフォームのサイズ互換機能(バーチャルHVGA表示エリアなど)に頼らず、自らUIをコントロールすると通知した事になります。スクリーンサイズ属性を”false”に設定した場合、そのスクリーンサイズ向けに設計していないと通知した事になります。サポートしないスクリーンサイズによって効果は変わります。

  • largeScreen=”false”とした場合、largeScreenの端末にもインストールは可能です。largeScreenで実行しようとした時に、プラットフォームはそのアプリを互換モードで実行し、largeScreen上のnormalサイズ、medium密度エリアに描画されます。互換モードでの表示例はこちらを参照してください。
  • smallScreen=”false”とした場合もsmallScreenデバイスにインストールは可能です。しかし、アンドロイドマーケットでフィルタリングされて、smallScreenデバイス向けには表示されません。結果として、この設定をする事により、smallScreenデバイスへのインストールを防ぐ事ができます。

android:anyDensity=”true”とした場合、プラットフォームに対し、全てのピクセル密度に対し、実際のスクリーン寸法、pixelを使ってアプリケーションが自らコントロールすると通知した事になります。この場合、アプリケーションはUIのサイズ等をdipで定義する必要があり、全ての実際のpixel値等をandroid.util.DisplayMetrics.densityで得られる要素を使ってリサイズしなければなりません。

android:anyDensity属性はプラットフォームが行う、画像リソースの事前リサイズには適用されません。これは常にデフォルトで実行されます。

以下の例は、全ての密度でlarge,normal,smallのスクリーンをサポートすると定義したマニュフェストの例です。

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:resizable="true"
android:anyDensity="true" />
</manifest>

属性のデフォルト値
<aupports-screens>のデフォルト属性値は、android:minSdkVersionによって異なります。もし定義されていればandroid:targetSdkVersionも同様です。

 

サポートされるスクリーンの範囲

Android1.5以前のプラットフォームは単一のスクリーン設定(HVGA320×480解像度の3.2インチスクリーン)のみをサポートしていました。故に、アプリケーション開発者はそのスクリーンに特化したアプリケーションを書く事ができ、他のスクリーンで表示される事を心配する必要がありませんでした。

Android1.6以降は、多くの新しい形やサイズのデバイスが登場してきた事を受け、複数のサイズ、解像度へのサポートを追加しました。これによって、開発者はデバイスとスクリーンの範囲に、適切な表示をするように設計しなければならなくなりました。

アプリケーション開発者が複数デバイスに対応したUIを設計する手法を単純化する為、及び、既存のアプリケーションにインパクトを与える事無く、より多くの端末を受け入れる為、以下の通り、実際のスクリーンサイズ、解像度をいくつかの範囲に分類します。

  • 3つの標準サイズ
    • large
    • nomal
    • small
  • 3つの標準ピクセル密度
    • high(hdpi)
    • medium(mdpi)
    • low(ldpi)

アプリケーションは必要なら何れの標準サイズ向けにもカスタマイズしたリソース(主にレイアウト)を提供できます。また、ピクセル密度についても同様にそれぞれの標準ピクセル密度毎にリソース(主に画像)を提供できます。アプリケーションは端末のスクリーンの実際の物理的なサイズやピクセル密度を扱う必要はありません。実行時に、プラットフォームがデバイスの標準化されたサイズとピクセル密度に基づき、適切なサイズおよびピクセル密度のリソースのロードを実施し、それらを実際のスクリーンのピクセルマップに適合させます。

下表はいくつかの主要なサポートされているスクリーンをリストし、プラットフォームがそれらをどの様に標準化スクリーン設定にマッピングしているかを表しています。いくつかのデバイスは下表に掲載されていないスクリーンを使っています。(プラットフォームはそれらを同じ標準化スクリーン設定にマッピングします。)

table1_Examples of device screens supported by Android

上記の様に、様々なスクリーン設定が、nomalサイズでmedium密度の基本スクリーンを中心に配置されています。HVGAスクリーンが基本スクリーンとして使われています。何故なら、android1.5以前のアプリケーションはT-MobileやG1等に搭載されたHVGAスクリーン向けに書かれているからです。

プラットフォームは現在、表にある9種類のサイズ・密度設定をサポートしていますが、これら個々にカスタマイズしたリソースを作る必要はありません。プラットフォームは後述する堅牢な互換機能を提供しており、UIが適切に実装されていれば、あなたのアプリケーションをデバイスのスクリーンに描画する処理のほとんどをこの互換機能が扱います。

androidはどの様に複数スクリーンをサポートするのか

androidの複数スクリーンサポートの基本はビルトインされた互換機能で、実行されるデバイススクリーンに最適な方法によるアプリケーションリソース描画をまとめて管理します。プラットフォームはあなたのアプリケーションの描画処理のほとんどを扱いますが、同時に、どの様に表示させるかコントロールするキーとなる2つの方法を提供します。

  • プラットフォームは必要に応じて、サイズ、ピクセル密度を特定したリソースを提供する為の、リソース識別子のセットをサポートします。特定サイズリソースの為の識別子はlarge、normal、smallで、特定ピクセル密度リソースの識別子はhdpi、mdpi、ldpiです。これらの識別子は上記表の標準化されたサイズ、ピクセル密度に一致します。
  • プラットフォームはマニフェスト要素も提供します。この要素の属性であるandroid:largeScreens、android:normalScreens、android:smallScreensによってあなたのアプリケーションがサポートする標準化スクリーンサイズを特定できます。4つ目の属性である、android:anyDensityによってビルトインの複数密度サポートを適用するかしないか、決める事が出来ます。

実行時に、プラットフォームはデバイスに表示可能な最適な表示を行う為に、3種類のサポートをあなたのアプリケーションに提供します。

  • リソースの事前リサイズ(画像等)
    スクリーンのピクセル密度に基づいて、プラットフォームはあなたのアプリケーションからサイズ、密度を指定されたリソースをロードし、リサイズせずに表示します。もし、適切なリソースが見つからなかった時は、プラットフォームがデフォルトのリソースをロードし、スクリーンの標準化ピクセル密度にマッチする様に拡大、もしくは縮小します。プラットフォームは特定ピクセル密度ディレクトリからロードされたものでない限り、デフォルトリソースが基本密度であるmedium(160)向けに設計されたものとみなします。
    例えば、スクリーンの密度がhighの場合、プラットフォームは識別子hdpiでタグ付けされたリソースをロードし、それらをリサイズせずに使用します。もし、その様なリソースが見つからなかった場合、プラットフォームは代わりにデフォルトリソースを使用し、基本密度(medium)からhighにリサイズします。

    サイズ、密度特定リソースの作り方について、更に詳しくはResource qualifiersを参照して下さい。

  • ピクセル縦横サイズ、座標の自動調整
    アプリケーションが複数のスクリーンピクセル密度をサポートしていない場合、プラットフォームはアプリケーション内で使われている、全ての絶対座標、寸法、およびその他のピクセル数値(パディングやマージン等)を自動的に調整します。これはピクセルで定義されたスクリーン要素が基本密度(medium(160))で表示された時とほぼ同じ物理サイズで表示される様にする為です。プラットフォームはこのリサイズを裏で行い、また、物理ピクセルサイズに加え、リサイズされた全てのピクセルサイズをアプリケーションに報告します。

    詳しくは、Manifest attributes for screens supportのandroid:anyDensity属性項目を参照して下さい。

  • 大きなスクリーン向けの互換モード
    デバイスのスクリーンサイズがあなたのアプリケーションがサポートするサイズよりも大きい場合(Manufestの要素に基づく)、プラットフォームはアプリケーションを基本サイズ、基本密度で表示します。標準サイズよりも大きいスクリーンに対しては、黒背景上に基本サイズで表示します。

    例えば、largeに分類される、WVGAのmedium密度のスクリーンだが、アプリケーションはlargeスクリーンをサポートしていないケース。この場合、アプリケーションがスクリーンサイズを問い合わせた時にシステムが、320×480だと偽って報告します。アプリケーションをリサイズする代わりに、アプリケーションの320×480インターフェースが、切手の様に480×800のlargeスクリーン上に配置されるわけです。

    詳しくは、Manifest attributes for screens supportのandroid:anyDensity属性項目及び、Screen-Compatibility Examplesを参照して下さい。

    一般的に、これらの互換機能は、全てのアプリケーション(android1.5以前向けを含む)が殆どのデバイスで適切に表示出来る事を可能にします。特に、デバイスのスクリーンが基本サイズより大きい場合は。

    しかし、基本スクリーン向けに書かれたアプリケーションはQVGA等の小さなスクリーンに適切に表示させるためには多少の調整が必要である事を覚えておいてください。小さなスクリーンはスクリーンエリアが削減される為、デザイン、コンテンツ、機能が犠牲になる事を考える必要があります。

    詳しくは、Strategies for Legacy Applicationsを参照して下さい。

    androidドキュメント和約「様々なスクリーンのサポートについて」その1
    androidドキュメント和約「様々なスクリーンのサポートについて」その2
    androidドキュメント和約「様々なスクリーンのサポートについて」その3
    androidドキュメント和約「様々なスクリーンのサポートについて」その4
    androidドキュメント和約「様々なスクリーンのサポートについて」その5
    androidドキュメント和約「様々なスクリーンのサポートについて」その6
    androidドキュメント和約「様々なスクリーンのサポートについて」その7
    androidドキュメント和約「様々なスクリーンのサポートについて」その8

 

Androidはスクリーンサイズ、解像度が異なる様々なデバイス上で稼働する様にデザインされています。
Androidのプラットフォームは、アプリケーションの為に、全てのデバイスに渡って行っての環境を提供し、スクリーンにアプリケーションのUIを適用させる為の多くの困難を解消します。
同時に、Androidのプラットフォームは、特定のスクリーンサイズ、解像度で表示された場合の、アプリケーションUIを正確に制御できるAPIを提供します。

このドキュメントはAndroidプラットフォームによって提供される、スクリーンサポートの内容の説明、およびその使い方を解説します。

下記の記述に従えば、全てのサポートされる端末に適切に表示されるアプリケーションを一つの.apkとして簡単に作る事が出来ます。

もし、あなたが既にAndroid1.5以前向けのアプリケーションを公開しているなら、このドキュメントを呼んで、Android1.6以降の、様々なスクリーンで稼働しているデバイスにあなたのアプリケーションをどの様に適合されるか検討するべきです。

多くの場合、下位互換のみが必要とされますが、全てのサポートされたスクリーンであなたのアプリケーションをテストするべきです。

特に、QVGAの様な小さいスクリーンで動かしたいアプリケーションがあるなら、レガシーアプリケーションの為の戦略を参考にして下さい。

スクリーンサポートの概要
このセクションでは、androidプラットフォームのマルチスクリーンサポートの概要、このドキュメントとAPIで使われるテーマとコンセプトの解説、プラットフォームがサポートする、スクリーン設定のサマリー、とAPIとスクリーン互換性についての基礎を解説します。

テーマとコンセプト

Tagged with:  

よしよし。

別アプリで編集したbitmap画像を
ウィジェットの背景に取り込むテスト成功♪

このやり方行ける。

まだまだやる事たくさんあるけど、
年内のメジャーバージョンアップを目指して頑張ろう!

今日試して見た事を軽く書いときます。

appWidgetProviderアプリと画像編集用のActivityアプリをそれぞれ含む2つのパッケージを用意。

画像編集用アプリの詳細は省きますが、
以下の様に、同じ作者が作ったアプリにアクセスを許可するオプションを付けて内部メモリに画像を保存します。

static private final String FNAME = ”savedImage.png”;

try {
 FileOutputStream out =
  context.openFileOutput(FNAME,Context.MODE_WORLD_READABLE);

 bitmap.compress(CompressFormat.PNG, 100, out);

 out.flush();
 out.close();

 Toast.makeText(context,”Image saved.”, Toast.LENGTH_LONG).show();
} catch(Exception e) {
 Log.d(“DrawTest”,”saveImage exception:”+e.toString());
}

一方、appWidgetProvider側では以下の様に上記アプリが内部メモリに保存した画像を読み込みます。

RemoteViews rv = new RemoteViews(context.getPackageName(),R.layout.testwidget);
FileInputStream in = null;

try{
Context ctxt = context.createPackageContext(“com.hogehoge.drawtest”,0);

in = ctxt.openFileInput(FNAME);

Bitmap bmp = BitmapFactory.decodeStream(in);

rv.setImageViewBitmap(R.id.wgt_img, bmp);

appWidgetManager.updateAppWidget(appWidgetIds, rv);

} catch (Exception e) {
// TODO 自動生成された catch ブロック

Log.d(“TestWidget”,”Exception:”+e.toString());

e.printStackTrace();
}finally{
try {
in.close();
} catch (IOException e) {
// TODO 自動生成された catch ブロック
Log.d(“TestWidget”,”in close exception”);
e.printStackTrace();
}
}

上記の様に、パッケージ名を指定して画像編集アプリのContextを自作します。
そして、そのContextを利用して画像編集アプリ内の画像ファイルをbitmapとして取得しています。

これが出来る条件は以下の通り。
 ・二つのアプリのManifestに共通の作者によるアプリである事を明示する為の下記記述がある事。
  android:sharedUserId=”com.hogehoge.userid”

 ・二つのアプリの証明書が共通である事。

 ・ファイルが別アプリからの参照を許可する設定で保存される事。

これを満たせば自作アプリを複数パッケージに分割する事ができます。

使い所としては、
ボリュームのあるリソースを外出しし、利用有無をユーザにゆだねるとか、
複数アプリでリソースを共有するとか、色々ありそうに思います。

CliphWeatherでの使い方は乞うご期待と言う所で。
(もうバレバレかもしれないけれど。。。)

Tagged with: