タグ:備忘録 ( 18 ) タグの人気記事

続・Activity切り替え

カメラアプリには必須っぽいActivity切り替え。
そこにも、まだまだ罠が潜んでいた。

今自作しているアプリは、独自フレームワークを使っている。
Activityを継承したフレームワーククラスを作り、なるべく共通な要素をそこで処理し、
ゲーム毎に行うべき処理を、ゲームのメインクラスとして定義し、
フレームワークでインスタンスを生成している。

がActivityを継承したフレームワークは、そもそもActivity切り替えなぞ考えてない設計だった。
Activityを切り替えるたびに、この初期化部分が呼び出される。

レイアウトを作り変えるのが、切り替えの目的だから、毎回初期化部分が呼び出されないと困るわけだが、
その他の初期化部分は、なるべく一度しか処理されないようにしなければならない。

まあ、タッチライブラリの初期化、など、各種ユーティリティの初期化しか行ってないので、基本問題は無い。
と思いきや、ゲームクラスの初期化に問題があった。

シングルトン形式で、インスタンスを1つしか生成しないようにしているため、2回目以降の初期化(生成処理)は通過しない。
この初期化の中で、

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

これで、画面を横方向に固定している。
どちらの画面方向を使うかは、ゲームによって異なるので、フレームワークには入れなかった。

しかし、この処理は、毎回必要らしい。


初回起動・フレームワーク初期化、ゲームクラス初期化
 ↓
別のActivity切り替え
 ↓
元のActivityに戻る
 ↓
フレームワーク初期化・ゲームクラスはインスタンスがあるため、初期化スルー

とすると、画面設定が、任意方向可に戻るのだ。
面倒だのう。

あと、もう1つ。
これは、アプリ制作では、周知の事実だけど、Activity切り替え(View切り替え)を使うと、顕在化する。

AndroidOSにある、1つ戻るボタン(機能)。
これは、ホーム画面に戻る、ではなく、1つ前のVIEWに戻る、という機能なんだな。

ゲームで1つのVIEWしか使って無いと、ゲーム中に1つ戻ることで、ホーム画面に戻る。
が、Activity切り替えを導入し、一度切り替えると…。

1つ戻るボタンでは、永久に、アプリは終わらなくなる…。
[PR]
by miries | 2015-01-25 10:16 | Android

カメラとActivity切り替え

まだまだカメラアプリと格闘中。

中華タブレットから、F-10Dに戻ってアプリを起動すると…。
エラーの嵐!

なん…だと…。

ログ出力を見てみると、アプリ起動直後に、onDestroyが呼ばれ、その後、自動で再起動している。
そんなバカな。

以前は問題なく動いたはずだ。
何もなく Destroyが呼ばれるはずが無い。
改変の途中で、何かしらいけないことをやっているということか?

しかし、差分は大きい。探し出すのは不可能にちかい…。

いやまて。
通常、Destroyが呼ばれる=アプリ終了だ。
大抵、ぬるぽだったりするはずだ。

それが、そのままActivityが再起動するだと?
どこかでその現象みたことがあるぞ!

そう、画面の回転だ。
Androidは、画面が回転するだけで、Activityの破棄・生成が起きる。
しかし、それを回避するマニフェストは書いてある。

android:configChanges="orientation|keyboardHidden"

そう、これだ。
しかし、これと似たようなところに、原因があるはずだ!

…と目星をつけて、ぐぐると…見つけやしたぜ!

android:configChanges="orientation|screenSize|keyboardHidden"

なんと、APIレベル13以上から、orientation以外に、screenSizeもつける必要があるらしい。
そういえば、先日、API8⇒API16に上げたわ。

お 前 が 原 因 か!

つか、似たような原因じゃなくて、もろ回転じゃねーか!

ということで1つ解決したが、まだまだ残ってる。
IntentによるActivity切り替え後のカメラプレビューが表示されなかったり、
プレビューを開始すると落ちたりするのだ。

先は長い。
[PR]
by miries | 2015-01-23 23:33 | Android

カメラのプレビューとsurfaceViewのサイズ

カメラのプレビューサイズと、SurfaceViewのサイズについては、カメラアプリを作るときに必須なので、すでに多くのサイトで解説がなされているので、さらっとおさらい。

●カメラのプレビューサイズは、任意に決定できない。
サポートされているサイズセットの中から選ぶ

●プレビューサイズは、端末の画面サイズと同じとは限らない
(というか、一致しない方がデフォ)

●プレビューサイズを設定しても、最終的には、SurfaceViewのサイズになる。
(viewのサイズに、ViewGroup.LayoutParams.WRAP_CONTENTを指定した場合)

なので、16:9のアスペクト比を持つ画面いっぱいのViewに、4:3のプレビューを表示すると、横に伸びた映像になる。
この辺りを、どう解決するかで、みんながググる事になる。

一般的な解決方法は、SurfaceViewを作って、レイアウトにaddView() する際に、
プレビューの比率に合わせてサイズを指定することである。

しかしこのSurfaceViewのサイズ、一旦決めたら、変更するのがなかなか難しい。
もし、画面サイズが変わる端末があったら、プレビューが見切れたりしてしまう。

そんな、恐ろしい端末が、s5110bである!

b0163324_12252714.png
b0163324_12253662.png


画面下のアクションバーを(アプリ起動中でも)いつでも出し入れできるのだ。
アクションバーが消えているときは、画面一番下を横にスワイプすることで出てくる。

ちなみに画面サイズは、[800x480] [800x432]で、アクションバーの高さは48ピクセル、
割合にして、10%も変化してしまう。

アクションバーを出した状態で、カメラアプリを起動し、アクションバーを消すと、変な空白が生まれるわけだ。

この微妙な見た目に対応するためには、どうにかしてSurfaceViewのサイズを変更する必要がある。

画面サイズが変更されるので、onSizeChanged()が呼ばれるが、
名前の通り、サイズが変更"された"ときに呼ばれるメソッドだ。
ここで何をやっても何も起こらない。

そこで、見つけたのが、onMeasure() だ。

これは、画面サイズ変更時(だけではないが)に呼ばれ、
各Viewのサイズを算出して設定するメソッドだ。
ここで取得できるサイズは、変更後の新サイズで、試しに100x100を設定したら、きちんと反映された。

まあ、自力で算出しろってことだ。

そんなこんなで、実際のコード。
カメラプレビューは、アスペクト比4:3から変更するつもりがないので、固定で書き込んでいる。

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int widthMode= MeasureSpec.getMode(widthMeasureSpec);
int heightMode= MeasureSpec.getMode(heightMeasureSpec);

int w = MeasureSpec.getSize(widthMeasureSpec);
int h = MeasureSpec.getSize(heightMeasureSpec);

int dw = w;
int dh = h;

switch(widthMode) {
case MeasureSpec.EXACTLY:// 確定
break;
case MeasureSpec.UNSPECIFIED:// 自由
dw = h *4 /3;
break;
case MeasureSpec.AT_MOST:// 以下
dw = h *4 /3;
if ( dw > w ) {
dw = w;
}
break;
}
switch(heightMode) {
case MeasureSpec.EXACTLY:// 確定
break;
case MeasureSpec.UNSPECIFIED:// 自由
break;
case MeasureSpec.AT_MOST:// 以下
dh = dw *3 /4;
if ( dh > h )
dh = h;
break;
}

//サイズ反映
setMeasuredDimension(dw, dh);

}


[PR]
by miries | 2015-01-22 13:00 | Android

Windows7の設定

備忘録に入れたと思ったら入っていなくて焦った。

会社でWindows7のマシンを乗り換えたのだが(実質無駄な乗り換えだが)、
新しくWindows7を使い始めたときの設定で、重要な設定があったはずなのだが…。

と思い出し、このブログを検索したが見つからず。

過去を思い出し、ようやく、UACの設定レベルを最低にすれば良い、というのを思い出した。
これをしないと、Program Files以下の設定が、複数できるんだよ。

例えば、FFFTPだと、通常起動した場合と、管理者権限で起動した場合で、
表示されるプロファイルが異なるのだ。

インストールされている場所は、Program Files以下で固定なのに、
アカウントによってファイルが異なる…それがUAC。

確かにファイルを保存したのに、更新されてないときは、驚愕したわー。
[PR]
by miries | 2014-01-15 00:32 | デジタル系

JScrollPaneのスクロール

JScrollPane jsp

を定義して、思いっきり縦長のスクロールリストを表示する。
一番下に追加して再描画する際、自動でスクロールリストを最下部に移動したい。

JScrollBarクラスに、setValue()で値をセットするメソッドがあるが、
これではスクロールしないというのは周知の事実:-P

でも、どうしても一番下にスクロールしたい…という場合は、Viewportを設定するそうだ。

jsp.getViewport().scrollRectToVisible(new Rectangle(0, Integer.MAX_VALUE - 1, 1, 1));

これが、汎用で使えるコードである。

…と、ここまでがGoogle先生が教えてくれた内容なのだが、実際に使ってみると、これにも不具合がある。

スクロールリストが既に一番下にある状態で、このViewportを設定する(例えば連続で2回呼ぶ)と、一番上に戻ってしまうのだ!

なんということでしょう。

というわけで、確実に自動で一番下にするには、まず一番上に戻すのがいいだろう。

jsp.getVerticalScrollBar().setValue(0);
jsp.listPane.getViewport().scrollRectToVisible(new Rectangle(0, Integer.MAX_VALUE - 1, 1, 1));

これで今のところはOKだった。
[PR]
by miries | 2013-10-05 00:43 | ゲームを作る

Javaアプレットの警告画面

なんと!
例の警告画面は、Javaが出していたのか…。

http://www.java.com/ja/download/help/appsecuritydialogs.xml


これだよこれ、まさにこのダイアログっす。


しかも Java7 update21 からとか…。
Javaを使用する仕事が一段落したので、最新のUpdateを適用したのだが、それが原因とは。

----
黄色の警告の盾

アプリケーションが署名されていないか、証明書が有効ではないか、あるいはその両方であることを示します。証明書によって指定された識別情報を信頼できません。
----

署名をつけろと…?
しかしだよ、署名をつけたとしよう。

----
信頼できる認証局の証明書で識別されるアプリケーションに対するセキュリティ・プロンプト

----

これでも、実行ボタン押すのに勇気いると思うんだけど…?

さらに。
「カスタムカード」は、アプレット自体を配って、データ部分だけを自作して入れ替えてもらうゲームだ。
このアプレットに署名をしてしまうと…。
オレオレ署名だと、ネット上の至る所で私の書名付きアプレットが公開されることになるし、
正式な署名だと、動作しなくなるだろう。

うーむ、面倒くさいことになったものだ。
[PR]
by miries | 2013-05-15 16:13 | ゲームを作る

ウインドウ描画

最近は、CSSとかにも実装されている、1枚の絵から、ウインドウを描画する機能。
昔ながらの方法だと、画像を9分割して…という方法なのだが。

Androidでも、drawBitmapMeshを使えば、楽にできるのね。

24x24ピクセルのウインドウパーツ(8x8の9ブロック)があれば、
以下で描画可能。
canvasとimageは適宜に。
----
public static void drawWindow(int x, int y, int w, int h) {

float[] verts = new float[16*2];

int block = 8;

verts[ 0] = x;verts[ 1] = y;
verts[ 2] = x + block;verts[ 3] = y;
verts[ 4] = x + w -block;verts[ 5] = y;
verts[ 6] = x + w;verts[ 7] = y;

verts[ 8] = x;verts[ 9] = y +block;
verts[10] = x + block;verts[11] = y +block;
verts[12] = x + w -block;verts[13] = y +block;
verts[14] = x + w;verts[15] = y +block;

verts[16] = x;verts[17] = y +h -block;
verts[18] = x + block;verts[19] = y +h -block;
verts[20] = x + w -block;verts[21] = y +h -block;
verts[22] = x + w;verts[23] = y +h -block;

verts[24] = x;verts[25] = y +h;
verts[26] = x + block;verts[27] = y +h;
verts[28] = x + w -block;verts[29] = y +h;
verts[30] = x + w;verts[31] = y +h;

canvas.drawBitmapMesh(image, 3, 3, verts, 0, null, 0, null);

}
----
[PR]
by miries | 2012-12-18 12:06 | Android

レスポンシブルWebデザイン

最近、Webページのデザインで、レスポンシブルが流行っているということで、
早速自分でもテストすることにした。

色々なところに、ショーケースがあるので、それを眺めていたら、
想像以上にブラウザサイズに合わされていて驚愕。

こんなのどうやってデザインするんだよ…と思っていたら、
MediaQuery というのを使えば、一発でできるんだね。

MediaQueryの役割は、ブラウザサイズ(デバイスサイズでも可)によって、
使用するスタイルシートを分岐できる、というもの。

この分岐が、JavaScriptを使わなくても、
リアルタイムに変更されるのが素晴らしい。

ブラウザサイズに合わせて、ロゴなどの画像のサイズを変化させているページもある。
それらがどうやっているかは正確には見ていないが、
自分のテストでは、background-image の切り替えで簡単にできた。

仮に、ブラウザサイズを6段階判別するようにして、
それぞれに画像を割り当ててみた。

アクセスログを見ると、まず、ブラウザサイズにより分岐した、
最初の画像が読み込まれるのみ。

ブラウザサイズを変更すると、それに合わせた画像が読み込まれ、
元のサイズに戻しても読み込みは発生しない。

これは良いね。
スマフォとか回線が遅い端末にもぴったりだ。

JavaScriptやPHPなんかを使わなくても、インタラクティブなページが
こんなに簡単に作れるようになっていたとは。
[PR]
by miries | 2012-12-11 19:18 | デジタル系

バグFIXに二日もかかるとは。

今作っているAndroidアプリで、原因不明のバグ発生中。

シーン切り替え時に、一瞬画面が消えて、元の画面が出て、
それから新しいシーンになるというもの。

この一瞬消える原因が分からなかった。

が、実は一瞬消える方は正しくて、元の画面が出る方が間違い。

描画は2Dオンリーなので、SurfaceViewを使用している。
lockしたcanvasを渡しているだけで、特殊な設定は一切していないのだが、
標準でダブルバッファになっているらしい。

消えた後に元の画面が出るのは、このダブルバッファをクリアしていないためだ。

lock,unlockを使っているのに、内部はダブルバッファ?

うーむ。
[PR]
by miries | 2012-12-05 11:35 | Android

Androidあぷり

あ…ありのまま 今 起こった事を話すぜ!

『Android-SDKのバージョンを上げたら
eclipseが起動しなくなった』

な… 何を言ってるのか わからねーと思うが
おれも何をされたのかわからなかった…
頭がどうにかなりそうだった…
不具合だとかバグだとか
そんなチャチなもんじゃあ 断じてねえ

もっと恐ろしいものの片鱗を味わったぜ…


----
あ、eclipse界じゃ結構メジャーなスタンド能力なのか。

http://android2010.seesaa.net/article/265330785.html

eclipse.exe -clean.cmdを実行するだけでOKだとは。

うちのもこれで治りました。
[PR]
by miries | 2012-10-17 23:19 | Android