Androidプログラマへの道 〜 Moonlight 明日香 〜 - オートフォーカスを使用する
カメラのオートフォーカス機能を使用するには, Camera.AutoFocusCallbackインタフェースを利用する.

オートフォーカスの使用

写真を撮影する」を参照して, カメラで写真が撮影できるようにする.
  • src/CameraView.java
    • View#onTouchEventメソッドをオーバーライドする.
      • ビューへのタッチを検出すると, Camera#autoFocusメソッドでオートフォーカスを機能させる.
    • AutoFocusCallbackインタフェースのonAutoFocusメソッドをオーバーライドする.
      • オートフォーカスが完了すると, Camera#takePictureメソッドで写真を撮影する.
package com.moonlight_aska.android.camera01;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Size;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.SurfaceHolder;

public class CameraView extends SurfaceView
    implements SurfaceHolder.Callback, PictureCallback, AutoFocusCallback {
  private Camera mCamera = null;
  private static final String SDCARD_FOLDER = "/sdcard/CameraSample/";

  public CameraView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    SurfaceHolder holder = getHolder();
    holder.addCallback(this);
    // holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    // 保存用フォルダ作成
    File dirs = new File(SDCARD_FOLDER);
    if(!dirs.exists()) {
      dirs.mkdir();
    }
  }

  @Override
  public void onPictureTaken(byte[] data, Camera camera) {
    // TODO Auto-generated method stub
    SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd_kkmmss");
    String datName = "P" + date.format(new Date()) + ".jpg";
    try {
      // データ保存
      savePhotoData(datName, data);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      if(mCamera != null) {
        mCamera.release();
        mCamera = null;
      }
    }
    // プレビュー再開
    mCamera.startPreview();
  }

  private void savePhotoData(String datName, byte[] data) throws Exception {
    // TODO Auto-generated method stub
    FileOutputStream outStream = null;
    try {
      outStream = new FileOutputStream(SDCARD_FOLDER + datName);
      outStream.write(data);
      outStream.close();
    } catch (Exception e) {
      if(outStream != null) {
        outStream.close();
      }
      throw e;
    }
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub
    if(event.getAction() == MotionEvent.ACTION_DOWN) {
      // オートフォーカス
      mCamera.autoFocus(this);
    }
    return true;
  }

  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    mCamera = Camera.open();
    try {
      mCamera.setPreviewDisplay(holder);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // TODO Auto-generated method stub
    mCamera.stopPreview();
    // プレビュー画面のサイズ設定
    Camera.Parameters params = mCamera.getParameters();
    List<Size> previewSizes = params.getSupportedPreviewSizes();
    Size size = previewSizes.get(0);
    params.setPreviewSize(size.width, size.height);
    mCamera.setParameters(params);
    // プレビュー開始
    mCamera.startPreview();
  }

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
  }

  @Override
  public void onAutoFocus(boolean success, Camera camera) {
    // TODO Auto-generated method stub
    // オートフォーカス完了. シャッターを切る
    mCamera.takePicture(null, null, this);
  }
}