しかしAndroid 2.x (Gingerbread)では呼ばれていたonPreviewFrameが、Android 4.x (Ice Cream Sandwich)で動かしたら呼ばれなくなっていた。 その対策方法を見つけたのでメモしておく。
問題の起こるコード
class CameraPreviewSurface implements SurfaceHolder.Callback, Camera.PreviewCallback { // 中略 @Override public void surfaceCreated(SurfaceHolder holder) { mCamera = Camera.open(); if (mCamera != null) { try { mCamera.setPreviewDisplay(holder); mCamera.setPreviewCallback(this); } catch (IOException e) { if(camera != null) { mCamera.release(); mCamera = null; } } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mCamera.stopPreview(); // 中略 mCamera.setParameters(params); mCamera.startPreview(); } @Override public void onPreviewFrame(byte[] data, Camera camera) { // 中略 } }
そして、以下が対策済みのコード
class CameraPreviewSurface implements SurfaceHolder.Callback, Camera.PreviewCallback { // 中略 @Override public void surfaceCreated(SurfaceHolder holder) { mCamera = Camera.open(); if (mCamera != null) { try { mCamera.setPreviewDisplay(holder); // 不要 mCamera.setPreviewCallback(this); } catch (IOException e) { if(camera != null) { mCamera.release(); mCamera = null; } } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mCamera.stopPreview(); // 中略 mCamera.setParameters(params); mCamera.setPreviewCallback(this); // stopPreviewを呼んだら、startPreviewを呼ぶ前にsetPreviewCallback mCamera.startPreview(); } @Override public void onPreviewFrame(byte[] data, Camera camera) { // 中略 } }
stopPreviewを呼ぶとそれ以前のsetPreviewCallbackは無効になるらしい。
参考にしたページ
Android Camera - A Problem I Spent Almost Twenty Hours On
Thanks!