アプリ作っている作りたい作れよな

 相変わらず Eclipse が不安定で /workspace/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi の切除手術を終えたばかりです。対処療法も限界のような気がします。
 
 そんな状況にもめげずに新たなアプリ作成を開始しております。
 今日作ったテスト画面がこちら。
 device-2014-07-24-212217
 よくある「tic tac toe」(和名「三目並べ」)ではありません。
 画面をタイミングよくタッチするカジュアルゲームに仕上げるつもりです。詳細は・・ひみつ(はあと)。
 
 難しいゲームシステムにするつもりもなく、新たに勉強するのも外部サービスを利用したランキング機能位かなぁと考えているので、それほど時間をかけずに仕上げたいところ。
 
 既に次のアプリに思いを馳せる。
 
 第一候補は、見た目ロールプレイングゲームのようだけど迷路ゲームであり(名作「ウィザードリー」っぽく)、その実パズルゲームであるというアプリ。これは、手間がかかる。上下2画面にしたい。あぁ難しそう!
 
 第二候補は、国旗を学習するアプリ。国旗のフリー素材が容易に入手できることから激戦区のジャンルですが、四択問題や神経衰弱ではないシステムをぼんやり考慮中です。国旗素材は準備済みです。
 
 しかし、その前にいい加減完成させねば、と思っているのが、これ。
 device-2014-05-26-004543
 5月26日に記事にしてからの進捗率 0%。

大ハマリ再び・・eclipseのAndroid SDK Content Loaderが0%のままです

 7月7日に eclipse をアップデートしてフリーズしてしまった顛末を書いたのですが、再び止まってしまいました。
 今回は、あわてて eclipse を削除したりしないで、じっくり調べてみましょう。うん、そうしよう、そうしよう。
 
 止まってしまったのは、起動時の Android SDK Content Loader による SDK 読み込み時です。進捗 0% のまま動きません。10分くらい待ってました。

 そこで、強制終了の後、-clean オプションを付けて起動させる。が、同様に動きません。
 次に・・・と、もう他の手立てを知りませんからね。Google 先生に聞いてみました。
 
 結構な検索数があって、ポピュラーな不具合のようですね。
 おぉ、まったく同じ境遇の方発見!解決法も載っているのですが、手順が多いのでもう少し調べてからにします。
 
 eclipse の設定ファイルを削除する方法が多数を占める中、新たなアプローチの解決法見っけ。
 android 自体の設定ファイルを操作するのですね。あぁ、危険な香り・・試してみたい・・。
 端から再インストール覚悟で調べてますからね、躊躇することなく手順通りに作業してみました。
 
 動いた。
 原因はわからずとも、動いた。

 また起こりそうな予感がするので、手順をメモっておきます。
 
1 タスクマネージャーからフリーズしている eclipse をキルする。
2 エクスプローラーでユーザーフォルダを開く C:\ユーザー\”ユーザー名”\
3 アンドロイドフォルダを見付ける \.android (隠れフォルダになってるかもよ)
4 その中の “cache” フォルダを削除する
5 ”ddms.cfg” ファイルも削除する
6 eclipse を起動する
7 幸せ(ハート)

同じ処理でも backボタンからだとエラーとなる

 AndEngine をベースとしたアプリ「秘密のスライドパズル」では、最大32×57+4隅の1828もの Sprite を貼り付けています。
 これだけの数を貼り付けると Android 2.3.3を積む我が愛機の snapdragon 1GHz では、さすがにもたつきます。描画が遅れるのは、まあ、仕方ないですね。
 
 ところが、描画時ではなく Scene 遷移時の Sprite の除去時にエラーが出るのです。しかも、まったく同じ処理であっても、画面上のタッチイベントから処理した場合はエラーとならず、ハード上の back ボタンから処理した場合に ArrayList.throwIndexOutOfBoundsException error を吐くのです。
 具体的には、Scene 遷移時の detachChildren()、clearEntityModifiers()、clearTouchAreas()、clearUpdateHandlers()、detachSelf()、dispose() 処理時にエラーとなります。
 
 どゆこと?
 
 実は、以前のアプリにもこのエラーが出る場合もあったのですが、TimerHandler で処理タイミングずらして何となく解決していたのですね。
 今回は、Sprite 数が多いからでしょうか。タイミングずらしても確実にエラーとなり、根本的に解決しなければならないようです。
 
 エラーは「ArrayList のインデックスありませんよ」ですからね、何の ArrayList でしょう。
 ログを見るとEntity の onManagedDraw() での描画リストが処理時に空となっているからのようです。削除しているのに描画でのエラーとは、意表をつかれました。
 back ボタンからの処理時のみ描画リストがないということは、back ボタンの処理は UIスレッドで動いているのでしょうね。処理が多いときに完了を待たずに UI 別スレッドから描画処理が入るものだから、件のエラーが出ると・・・、全く確認していないのですが、そう間違ってもいないのでしょう(適当)。
 
 解決方法を Google 先生に聞いたところ、Andengine フォーラムに記事がありました。
 detach 処理を別スレッドにしてしまう方法とdetach 処理前に Engine を一時ロックしてしまう方法があるようです。う~む、別スレッドに入れて解決するのであれば、前段の仮定は間違っているということでしょうか?
 
 両方を試してみたところ、別スレッド処理は同じエラーを吐くようです。この解決方法は違う原因のエラーなのでしょうかね。英語がわかるようになりたいものです。
 
 兎にも角にも

		final EngineLock engineLock = mEngine.getEngineLock();
		engineLock.lock();
		gameScene.disposeScene(); // 子 Entity の削除やらをたっぷり処理
		gameScene = null;
		engineLock.unlock();

と、エンジンをロックして問題解決です。
 
 まだまだ知らないクラスが山ほどあるね。

「秘密のスライドパズル」公開

 Android アプリゲーム界隈でも激戦区であるスライドパズルゲームにまたもや参戦しました。誰でも作れるからね。
device-2014-07-14-005255 device-2014-07-14-005333 device-2014-07-14-005356
今回のアプリの主な機能は
 
・ アプリで撮った写真をスライドパズル化
・ 保存してある写真もスライドパズル化
・ スライドパズルは、3×5、4×6、5×8ピースの3パターン
・ 加えて、パズルとしては解けそうにもない11×19(Lモード)、20×34(Mモード)、32×57(Hモード)の「秘密のスライドパズル」
・ パズルを解くのが難しい場合には、ピース上に数字を表示
・ それでも解けない場合には、自動で手順を再現し解答
・ 「秘密のスライドパズル」は、瞬時に再現することも可
・ 解答手順は、パズル化した画像に記録されているので、画像を配布するだけでアプリで再現
・ パスコード(数字6桁)の設定
・ Gメールと連携したメール送信(ツイッター連携諦めて、こちらに鞍替え)
・ 480×800ピクセルのオートフォーカスカメラ
・ シャッターボタンの自由な位置設定
・ 端末のメディア音量によって調整できるシャッター音
 
と、スライドパズルにしては高機能です。
140714023232 140714023311 140714125601
 順に5×8、11×19、32×57で、この画像をアプリで読み込めばスライドパズルとなるわけです。我ながら地味に凄い。(32×57はパスコード「111111」が設定されています。)
 
 しかし、これらが機能するかは Android 2.3.3 の1機種 480×800 でしか確かめていないのですね。私が使っている機種です。未だ 2.3.3 です。現役です。
 
 昨今の高解像度のディスプレイやカメラの違いは吸収できるように組んだはずなのですが・・・確かめようがない。
 
 また、SDカードのパスを取得するため Environment.getExternalStorageDirectory() を使っているのですが、Android 4.4 ではそもそも外部SDカードは自由に使えないようで内部のパスを返すそうです。そんなんで動くの?
 さらにその場合、メール添付の画像パスは外部SDカードのパスでないと動かないとの記事もあり、この部分も気にかかるところです。
 
 そんな訳で不具合の報告を大々的に募集中です。
ic_launcher-web ssp_QRcode  
 よろしくお願いします。

Twitterに画像を添付して起動、成功、ところが

 Eclipse の復旧作業もようやく終わりました。
 今回のクラッシュの原因はわからずじまいで、役に立つ情報もなく申し訳ない。最後の手段は「再インストールしてプロジェクトをインポートする」であることは間違いなさそうです。
 復旧した Eclipse の日本語化はしていません。すると何かしら不具合が出そうな予感がするので英語表記のまま使っています。予感が結構当たるのです。
 
 アプリ作成の再開です。
 
 撮った写真をその場でスライドパズル化するアプリ「秘密のスライドパズル(仮題)」作成も佳境に入り、今は、ツイッター連携とカメラ周りをいじっております。
 device-2014-07-10-000117
 こんな画面からツイッターボタンを押すと
 device-2014-07-10-000222
 画像を添付して Twitter アプリが起動します。やれば出来るもんだね。
 
 早速、このままツイートしてみて、ツイートされた画像を保存して、アプリに読み込み、さあパズルとして動くかな・・・とテストしたら、ただの画像としか認識しません。
 調べてみると Twitter に添付された画像は jpg に変換されてしまうのですね。これは、困る。

 スライドパズル化された写真には、解答手順を埋め込んであるので、pixel 情報が変わってしまうと復元できないんですよ。圧縮してしまう jpg ぢゃダメなんです。png ぢゃないとダメなんですよ。あぁうあぁああ・・(号泣)。
 
 5分ほど打開策を考え、導かれた結論は「諦める」。なんと潔いのでしょう。
 使われぬコードを載せておきます。

public void tweet(final String message, final String path){
	Intent intent = new Intent(Intent.ACTION_SEND);
	intent.setType("image/png");
	intent.putExtra(Intent.EXTRA_TEXT, message);
	intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + path));
	String appName = "com.twitter.android"; 

	final PackageManager pm = getPackageManager();
	final List<?> activityList = pm.queryIntentActivities(intent, 0);
	int len = activityList.size();
	for(int i = 0; i < len; i++){
		final ResolveInfo app = (ResolveInfo)activityList.get(i);
		if((app.activityInfo.name.contains(appName))){
			final ActivityInfo activity = app.activityInfo;
			final ComponentName name = new ComponentName(activity.applicationInfo.packageName, activity.name);
			intent.setComponent(name);
			startActivity(intent);
			return;
		}
	}
}

 Intent 経由の画像添付には、いろいろな手法があるようなのですが、Twitter 狙い撃ちで画像を添付させる方法は、調べた限りこれが良さげ。
 
 そうそう、以前「カメラの設定がどうやっても横向きにしかならない。縦にしようとするとプレビュー画面が細長くなってしまう。・・・そこで、カメラ画面以外はダミーの Entity に貼り付けて270度回転させて表示するといった回りくどいことやっています」というのは、勘違い(というか、API 8 からターゲットにしていたから)。
 API 9 以降なら mCamera.setDisplayOrientation(90); であっさり縦配置になりました。

 
 アプリ作成は計画的に。