端末の向きを変えると異常終了

 端末の向きを変更すると異常終了する。
 作ってるアプリを起動し、「横向き(LANDSCAPE)←→縦向き(PORTRAIT)」の変更をするとアプリが異常終了するんだ。
 どうも Activity が初期化されてしまうのが原因のようだ。
 Android では画面の向きを変える際、Activity が初期化されてしまうらしい。
 それで予期しない初期化が起きて、異常終了するみたい。

 それじゃ、画面の向きを固定すればいい話し。
 でも、固定したくない場合もあるよね。
 その場合、「向きを変えても初期化しない」ようにすればいい。

Manifest の設定

 初期化しないようにするには、AndroidManifest.xml に configChanges=”orientation” を追加する。

<activity android:name=".XmSpriteView_Test"
		android:label="@string/app_name"
		android:configChanges="orientation">
</activity>

 orientation は、初期化をAndroid に任せず、アプリが行うということらしい。

 この設定は、eclipse の機能を使うと簡単に追加・設定できるよ。

1. eclipse でAndroidManifest.xml を開く

2. ウィンドウ下にある、「アプリケーション」タブをクリック

3. 設定するActivity をクリック

4. 右下のエリアにある、「Config changes」の「選択」ボタンをクリック。
 するとダイアログが出るので、その中の「orientation」をチェック。

 以上で設定が追加される。

Posted in アプリ設定, 画面. Tags: , , . 端末の向きを変えると異常終了 はコメントを受け付けていません。 »

「ピクセル密度」ってナニよ?

 さて。
 端末でアプリを実行すると、「画像表示(View)が拡大されてしまう」不具合について。
 (参照:「画面サイズ設定」ってナニよ?)
 原因は、画面サイズだと思ったんだけど、そうではなかったみたい。
 振り出しに戻る…。
 でも、ヒントはあった。
 それが「ピクセル密度」

「ピクセル密度」ってナニよ?

 ピクセル密度は、「1dotを何pixelで表すか?」というもの。
 何の役に立つのかというと、「表示されるものは、どの環境でも、同じ大きさで表示される」。
 17インチモニターでも、15インチモニターでも、そこに表示されるものは、同じ大きさになるってワケ。

 じゃ、なんで、画像が拡大表示しまうのか?
 それは画面と画像のピクセル密度が合っていないから。
 画像のピクセル密度が、画面の密度より低いため、拡大表示されてしまうんだ。
 PhotoShopやGIMPなんかで、印刷解像度を低くした時と似てる。
 「ピクセル密度 = 印刷解像度」みたいに捉えるとわかりやすいかもね。
 Androidでの表示は、WYSWYGの仕組みに近いんだ。

ピクセル密度を調べる

 ピクセル密度は、下記の方法で調べられる。
 実行すると、ログにピクセル密度が書き出されるよ。

	DisplayMetrics metrics = getResources().getDisplayMetrics();

	Log.d( "TEST", "density=" + metrics.density );

 DisplayMetrics では、画面に関する他の情報も取得できる。

	DisplayMetrics metrics = getResources().getDisplayMetrics();
	
	Log.d( "TEST", "density=" + metrics.density );
	Log.d( "TEST", "densityDpi=" + metrics.densityDpi );
	Log.d( "TEST", "scaledDensity=" + metrics.scaledDensity );
	Log.d( "TEST", "widthPixels=" + metrics.widthPixels );
	Log.d( "TEST", "heightPixels=" + metrics.heightPixels );
	Log.d( "TEST", "xDpi=" + metrics.xdpi );
	Log.d( "TEST", "yDpi=" + metrics.ydpi );

 ちなみに。
 「画面サイズ設定ってナニよ?」で画面サイズを調べた時、画面サイズは 533×400 だった。
 それぞれに、ピクセル密度:1.5 をかけると、800×600 になる。
 ちょうど、normalScreens での値とlargeScreens での値になるね。

画像リソースのピクセル密度設定(画像解像度設定)

 拡大表示される原因は、ピクセル密度の違いにあることがわかった。
 じゃ、画面のピクセル密度に、画像のピクセル密度を合わせればいいワケだ。
 でもソレってどうやるの…?

 印刷解像度をいじくったリソースを使用してもダメ。
 ピクセル密度は、画像リソースだけで行う設定じゃないんだ。

 ピクセル密度の設定は、Eclipseプロジェクトでも行うんだ。
 正確には、設定ではないんだけどね。(^_^;

 大抵、画像リソースは、drawable ディレクトリに置くよね?
 それと同じで、それぞれのピクセル密度のディレクトリに、最適化した画像リソースを置くんだ。

	drawable-ldpi … 120dpi( low )
	drawable-mdpi … 160dpi( medium )
	drawable-hdpi … 240dpi( high )

 たとえば、medium で533x400dot の画像の場合、drawable-hdpi に800x600dot に拡大した画像リソースを置く。
 そうすることで、動作環境がdensityDpi = 240(high)だったら、画像リソースはdrawable-hdpi から使用される。
 Android は動作環境に合わせて、それぞれから最適なピクセル密度のリソースを使用してくれるって仕組み。

 最適なリソースがない場合、Android が自動的に拡縮調整してくれる。
 ただし、基準はmedium(160dpi)。
 つまり、drawable にだけ置くと、リソースをmedium として拡縮処理をしてしまう。
 high(240dpi)の環境で表示すると、拡大表示されてしまうんだね。

 これは便利な仕組みなんだけど…ゲームなんかでは困った仕組みだよ。
 ゲームの場合、テレビのようにdpi調整はしないで欲しい…
 この場合、drawable-nodpi ディレクトリにリソースを置く。

	drawable-nodpi … dpi調整をしない

 今回、drawable ディレクトリにあったリソースを、drawable-nodpi へ移すことで、拡大表示されてしまう不具合は解消されたよ。

プログラムからピクセル密度(画像解像度)を設定する

 ピクセル密度は、リソース・ディレクトリで対応できることがわかった。
 でも、ソレってデータがリソースの時だけ。

 画像データを外部参照する時は…?

 外部参照だけじゃなく、プログラム側からピクセル密度を設定したい場合もあるよね。
 そこでピクセル密度を設定できるか、ざっと調べてみたよ。

◆Canvas

	int	 getDensity()
	void	 setDensity(int density)

http://developer.android.com/reference/android/graphics/Canvas.html

◆Bitmap

	int 	getDensity()
	void 	setDensity(int density)

	int 	getScaledHeight(int targetDensity)
	int 	getScaledWidth(int targetDensity)

http://developer.android.com/reference/android/graphics/Bitmap.html

◆BitmapDrawable

	void	 setTargetDensity(int density)
	void	 setTargetDensity(DisplayMetrics metrics)
	void	 setTargetDensity(Canvas canvas)

http://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html

 以上からすると、今回の不具合には、Viewで使ってるCanvas にピクセル密度を設定すればいいみたい。
 そこでこんな風↓にしてみたよ。

	Canvas canvas;
	Bitmap scrImg = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888 );
	
	scrImg.setDensity( 160 );
	Log.d("TEST", "scrImg density = " + scrImg.getDensity() );
	
	Canvas scrImg_canv = new Canvas( scrImg );
//	scrImg_canv.setDensity( 160 );
	Log.d("TEST", "Canvas density = " + scrImg_canv.getDensity() );

 Canvas に直接、設定するのではなく、元になるBitmap の密度を設定してみた。
 Bitmap の設定がCanvas に引き継がれるか、確かめたかったため。
 実行してみると、設定値はちゃんと引き継がれていた。

 表示する画像データは、drawable ディレクトリに置いた画像リソース。
 medium(160dpi) と認識されるので、setDensity で設定する値も160にしてある。

 以上で、拡大表示される不具合は解消できたよ。

 この設定は、他のことにも使えそう。
 たとえば、動的に値を変えて、拡縮操作の代わりにするとか。
 まぁ、setBounds の方が使い勝手はいいから、意味はないだろうけどね。(^_^;

Posted in Bitmap, ピクセル密度. Tags: , , , , , , , , . 「ピクセル密度」ってナニよ? はコメントを受け付けていません。 »

「画面サイズ設定」ってナニよ?

 エミュレータ・ベース(VBox)で作ってたアプリを、端末で実行したら拡大表示されてしまった。
 いや、拡大表示っていうのは、正確じゃない。
 画像表示は拡大されて、ボタン等は横幅が圧縮されてしまってる。
 ちょうど、”小さな画面” に押し込まれた感じ。なんだけど…。

	VBoxの画面サイズは、800x600
	端末のタブレットも、800x600

 画面サイズは同じなのに、これはどういうことなんだろ…?

画面サイズを調べる

 原因は「端末の画面サイズ」だろうと予想がつく。
 なぜなら、ボタン等の左右端は、画面端から一定の長さを保つようにしているから。
 だから小さい画面になると、左右幅が圧迫されて横幅が小さくなってしまうんだ。
 でも前述のように、端末は800×600のハズ…。
 なにはともあれ、画面サイズをまず調べてみることにした。

 画面サイズは、下記方法で取得できる。

◆Activityの場合

	WindowManager wm = (WindowManager) getSystemService( Activity.WINDOW_SERVICE );
	Display display = wm.getDefaultDisplay();
	int width = display.getWidth();
	int height = display.getHeight();

◆Viewの場合

	WindowManager wm = (WindowManager) context.getSystemService( Context.WINDOW_SERVICE );
	Display display = wm.getDefaultDisplay();
	int width = display.getWidth();
	int height = display.getHeight();

 結果は…

	width  = 533
	height = 400

 やはり、画面サイズが小さいようだ。
 とすると、アプリ側で画面サイズの設定が必要…ということなのかな?

実は必要、画面サイズ設定(解像度設定)

 調べると、AndroidManifest.xml に supports-screens が必要らしい。
 supports-screens は、アプリでサポートしている画面解像度を設定するようだ。
 たとえば、下記のような感じ。

	<manifest xmlns:android="http://schemas.android.com/apk/res/android">
		<supports-screens
			android:largeScreens="true"
			android:normalScreens="true"
			android:smallScreens="true"
			android:anyDensity="true" />
	 </manifest>

 それぞれの意味は…

	largeScreens … ラージスクリーンのサポート
	normalScreens … ノーマルスクリーンのサポート
	smallScreens … スモールスクリーンのサポート
	anyDensity … ピクセル密度を調整可能

 ということのよう。
 これらの設定がない場合、解像度設定は、SDK Version の設定(後述)に従うらしい。
 そして、SDK Version の設定もない場合、すべてfalse となるらしい。

 supports-screens もSDK Version もない…
 その場合は、SDK 1.5相当のサポートとなり、normalScreens で動作することになる。
 つまり、「端末がlargeScreens の解像度でも、normalScreens の解像度で動作」する。
 ──今回のような「小さな画面サイズ」になってしまうようだ。

 PCに例えると、「17インチ・モニター(1024×768)で、15インチ設定(800×600)」にした感じかな。
 それと、これには逆の現象もあるらしい。
 本来、画面いっぱいに表示されるアプリが、小さく表示されてしまうようなんだ。
 原因は同じで、supports-screens もSDK Version の設定もないせいで起きるみたい。

 現在、作っているアプリは、800×480での動作を対象としている。
 なので、下記を追加したことで、画面サイズの問題はひとまず解決。

	<supports-screens
		android:largeScreens="true"
		android:anyDensity="true" />

SDK Version の設定

 前記 supports-screens とは別の設定でも、画面サイズを設定できる。
 別の設定とは、minSdkVersin もしくは targetSdkVersion の設定。
 それぞれは…

	minSdkVersino … 指定SDKバージョン以上で動作
	targetSdkVersion … 指定SDKバージョンでのみ動作

 …ということらしい。
 なので正確には、画面サイズ設定ではない。
 しかしこれらの設定をすると、SDKでサポートしている設定が supports-screens に設定されるため、同様の結果がえられるんだ。

 今回、下記を追加したことでも、画面サイズの問題は解決した。

	<uses-sdk android:minSdkVersion="4" />

※. 参考資料
http://developer.android.com/guide/practices/screens_support.html

未解決がひとつ…

 さて。
 画面サイズの問題は、supports-screens もしくは、minSdkVersion で解決した。
 けれども、「画像表示が拡大されてしまう」不具合は直らなかった。
 これはピクセル密度が関係した不具合で…
 解決方法は、またページを改めて。
 →「ピクセル密度ってナニよ?」

by the way…

 ここらへんって、基本中の基本っていうか、すごく重要なことだと思うんだけど…。
 手元にある緑本には記述が見当たらない。
 なんだかなぁ…。
 入門書だからこそ、解説してほしい事項なのになぁ。

Posted in アプリ設定, 画面. Tags: , , , , , . 「画面サイズ設定」ってナニよ? はコメントを受け付けていません。 »

端末実機をUSB接続でデバッグ・ターゲットにする

 端末をUSBで接続して、ハードウェア・エミュレータにするよ。
 これで開発も快適になるハズ。

ドライバーの入手

 開発環境がWindowsの場合、単純に接続しても認識しない。
 デバイス・ドライバーが必要になるんだ。
 そこでまず、ドライバーの入手ということになる。

 入手は、「SDK and AVD Manager」から行う。
  ( http://developer.android.com/sdk/win-usb.html )
 開発環境を構築したときと同様、ManagerからDownLoadすればOK。
  ( Third party Add-ons → Google.Inc.add-ons → Google Usb Driver package )
 ただし、この時点ではまだインストールされていないので、注意。

端末の設定

 PCに接続する前に、端末の設定をする。
 「設定 → アプリケーション」メニューを出して、「不明な提供元」のチェックボックスをONにする。
 同じメニューから「開発」メニューを出して、「USBデバッグ」のチェックボックスをONにする。
 ついでに「スリープを無効」をONにすると、USB接続時にスリープしなくなるよ。

ドライバーのインストール

 端末をPCに接続して、ドライバーをインストールする。
 接続するとインストール・ダイアログが出るので、そこで入手したドライバーのinfを選択する。
  ( /androidSDK/google-usb_driver/android_winusb.inf )
 これで端末を認識すれば、完了。
 認識してくれない場合、ハブ経由をやめて、直接接続すると認識することがある。

 環境が構築できたら、Eclilpse を起動して試してみよう。
 アプリ実行すると、アプリが端末へ転送されて、起動するようになるよ。
 当たり前だけど、エミュレータの負担がPCからなくなって、コンパイルも起動も早い。
 快適、快適~♪

Posted in 開発環境. 端末実機をUSB接続でデバッグ・ターゲットにする はコメントを受け付けていません。 »

端末かってきたー

 買ったのは、miniPadってヤツ。
 いわゆる中華パッド。

 昨今の情勢からすると、大して安くはないんだけどね。
 タブレット型が欲しかったのよ。
 国産だとタブレット型ないんだもん…。
 WiMAXルーターがあるから、キャリア契約は必要ないし。

 当初は、Bpad 702(¥12,800)というのを買う予定だったんだ。
 感圧式だけど、2.2で値段的にとってもリーズナブル!
 でも公式マーケットに対応してないので、却下。

 代わりに浮上したのが、miniPadとdroPad。

 どっちも静電式で、ちがいはAndroidバージョンと画面解像度。
 droPadは、Android 2.2、800×480。
 miniPadは、Android 2.3、800×600。
 開発ターゲットは2.2を想定してるんで、その点ではdroPadの方がよい。
 だけど、800×600の解像度は魅力。
 解像度違いのテスト環境にもいいしね。

 外見は、iPadマンマなdroPadに軍配があがる。
 miniPadはオール・プラスチックなもんで、かなりチープ。
 けどdroPadは、筋力トレーニングができそうなほど重い…。
 miniPadは素材が素材だけに、かなり軽い。
 droPadを持ったあとだと、羽毛布団のように感じる。(^_^;
 まぁ、ここらへんは善し悪し。
 miniPadは強度面が、かなり心配だから。
 ”零戦とムスタング”みたいなモンかね。
 爆発するかも…という点では同じだけど。(笑

 結局、解像度が決め手となって、miniPadに決定。
 家に帰って色々、イジくり回して気づいた。
 バイブレーションないじゃん… (´・ω・`)
 うかつ… orz
 でも、droPadもなかったような気が…。
 ひと回り小さいタイプはあったんで、このサイズだとないのがフツーなのかもしれない。
 う~~、店で気づけよ、オイラ… (´Д`;)



Posted in 雑記. Tags: , , . 端末かってきたー はコメントを受け付けていません。 »