ページ

2013/08/24

[Android]失敗しないCamera#autoFocus()の使い方

Camera#autoFocus(AutoFocusCallback) | Android Developersが失敗すると
アプリが強制終了してしまうので気をつけて実装しなければいけません。
Camera#autoFocus() で失敗しないためのポイントを紹介していきましょう。

AndroidManifest.xml に記述を忘れない

基本中の基本です。
機種にオートフォーカス機能があるかどうかわかないので
android:required="false" を指定しています。
オートフォーカスが絶対に必要なアプリだったら android:required="false" にする必要はありません。
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

hasSystemFeature でオートフォーカス機能をサポートしているか確認する

android:required="false" にしたらオートフォーカス機能をサポートしていない機種も
アプリをインストールできるので Camera#autoFocus() を呼び出す前には必ずチェックが必要です。
public static boolean hasFeatureAutoFocus(Context context){
    boolean hasAutoFocus = false;
    PackageManager packageManager = context.getApplicationContext().getPackageManager();
    hasAutoFocus = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_AUTOFOCUS);
    return hasAutoFocus;
}

Camera#autoFocus() の連続呼び出し対策で Camera#cancelAutoFocus() を呼ぶ

Camera.AutoFocusCallback#onAutoFocus(boolean, Camera) | Android Developersが呼ばれる前に
次の Camera#autoFocus() が呼ばれると落ちるので事前にキャンセルする処理を入れます。
もはや上記のチェックも含めてラッパーメソッド作るのが一番楽です。
public void autoFocus(AutoFocusCallback autoFocusCallback){
    if(CameraUtils.hasFeatureAutoFocus(mContext)){
        mCamera.cancelAutoFocus();
        mCamera.autoFocus(autoFocusCallback);
    }
}

Camera#autoFocus() をカメラ起動直後に呼ばない

SurfaceHolder.Callback#surfaceCreated(SurfaceHolder) | Android Developersが呼ばれる前に
Camera#autoFocus() を呼ぶと落ちるので起動時にオートフォーカスをしないか、
状態をフラグ管理するか、try~catchで握りつぶすかのどれかになると思います。
DevCamera の Ver.0.0.2 では起動時の onResume で Camera#autoFocus() を呼んで
ARROWS X LTE F-05D で落ちるというバグがありました(※ Ver.0.0.3 で修正済み)
他の機種でも起こるかもしれませんが報告があったのは F-05D だけでした。
Camera#open() して Camera#autoFocus() する間に surfaceCreated が呼ばれないと
surfaceCreated が呼ばれる数ミリ秒前とかに Camera#autoFocus() が実行されて落ちます。
機種の処理速度によっては Camera#open() から surfaceCreated 呼ばれて
Camera#autoFocus() を呼び出すという流れになるので落ちずに済んでバグを見逃すという結果になります。
参考: Android Camera.autoFocus() failed | hitziger.net

また、Camera#autoFocus(AutoFocusCallback) | Android Developersにもあるとおり、
Camera#startPreview()Camera#stopPreview() の間でのみ有効らしいので
状態管理のフラグが必要かもしれません。

以上、失敗しない Camera#autoFocus() の使い方でした!

これで DevCamera の安定度が高まりました。ぜひ使ってみてください。
ダウンロードはこちら→ DevCamera - Google Play の Android アプリ