Xperia arcのカメラアプリを縦向きの画面に対応するためにしたこと

Xperia arcでカメラアプリを作っていて、端末を縦にしたときの対応をしようとしたらやたら苦労したのでメモしておく。

やりたかったことは、縦にしたときにプレビューが回転して、サイズも変えること。

端末を縦にするとなんかプレビューが回転せずに小さくなった。
そこで、Camera.Parametersで"portrait"をセットしてみたらException...

Android2.2以降はCamera.setDisplayOrientation()を使えばいいらしい。
サンプルコードをそのまま入れてみたらちゃんとカメラビューが縦になった。
のだけど端末を横に戻そうとするとまたもException...

Camara.startPreview()したままCamera.setDisplayOrientation()を呼ぶとダメらしい。
surfaceChanged()の最初でCamera.stopPreview()するようにしたらオッケーだった。

そのままBitmap取得しようとすると、横向きのまま取得されてしまうので、Matrixを使ってBitmapも回転してあげる。

public void onPreviewFrame(byte[] data, Camera camera) {
    Size size = mCamera.getParameters().getPreviewSize();
    int[] rgb = new int[(size.width * size.height)]; // ARGB8888の画素の配列
    ImageUtil.decodeYUV420SP(rgb, data, size.width, size.height);	
    Matrix matrix = new Matrix();
    matrix.postRotate(mOrientation);
    Bitmap originalBmp = Bitmap.createBitmap(rgb, size.width, size.height, Bitmap.Config.ARGB_8888);
    Bitmap bmp = Bitmap.createBitmap(originalBmp, 0, 0, size.width, size.height, matrix, true);		
    // 画像処理するタスクの生成
    AsyncTask imageProcessingTask = new ImageProcessingTask(view.getContext());
    imageProcessingTask.execute(bmp);
}

するとさらに大きな問題ががが。

撮影した画像をBitmapにして加工する処理をAsyncTaskでやるようにしているのだけど、処理中に端末の向きを変えると画像が保存されない...

ググってみるといろいろ見つかった。
画面の縦横切り替え時に元の画面を保存
起動時にDialogを表示させるActivityで、横向きLANDSCAPEから縦向きPORTRAITへ向きを変えたときに発生するエラーの対処方法

確かにActivityが破棄されている。
処理中にタイトルバーにプログレス表示しているのが消えるのも、ActivityのonDestory()が呼ばれてたからだったのか!

上の記事の通りAndroidManifest.xmlに、android:configChanges="keyboardHidden|orientation"を指定して、ActivityのonConfigurationChanged()をオーバーライドしたらActivityが再生成されなくなった。


以上をまとめると、Androidのカメラアプリを縦対応にするには、

  • AndroidManifest.xmlに、android:configChanges="keyboardHidden|orientation"を指定
  • ActivityのonConfigurationChanged()をオーバーライド
  • Camera.setDisplayOrientation()に向きに合わせてrotationを指定する
  • SurfaceViewを使っているなら、surfaceChanged()で呼ぶといい感じ
  • Camera.setDisplayOrientation()の前にCamera.stopPreview()を呼ぶ
  • 撮影した画像をBitmapとして使うなら、Matrix使って回転させてから使う

こんな感じか。疲れたー><