Androidプログラマへの道 〜 Moonlight 明日香 〜 - 写真にGPS情報を設定する
撮影した写真のプロパティに緯度・経度等のGPS情報を設定するには, カメラパラメータ(Camera.Parameters)を使用する.

GPS情報の設定

写真を撮影する」を参照して, カメラで写真を撮影できるようにする.

  • src/MainActivity.java
    • 位置情報を取得する」を参照して, GPSから位置情報を取得できるようにする.
    • 位置情報が変化した時に, 位置情報を保存する.
package com.moonlight_aska.android.camera01;

import android.app.Activity;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity implements LocationListener {
  private LocationManager mLManager = null;
  private CameraView mCameraView = null;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 画面をフルスクリーンに設定
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    // カメラ用ビューの設定
    mCameraView = new CameraView(this);
    setContentView(mCameraView);
    // GPSサービス取得
    mLManager = (LocationManager)getSystemService(LOCATION_SERVICE);
  }

  @Override
  protected void onPause() {
    // TODO Auto-generated method stub
    if (mLManager != null) {
      mLManager.removeUpdates(this);
    }
    super.onPause();
  }

  @Override
  protected void onResume() {
    // TODO Auto-generated method stub
    if (mLManager != null) {
      mLManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
    }
    super.onResume();
  }

  @Override
  public void onLocationChanged(Location location) {
    // TODO Auto-generated method stub
    if (mCameraView != null) {
      // 位置を保存
      mCameraView.setLocation(location);
    }
  }

  @Override
  public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub

  }

  @Override
  public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub

  }

  @Override
  public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub

  }
}
  • src/CameraView.java
    • Camera#getParametersメソッドで, Camera.Parametersのインスタンスを取得する.
    • Camera.Parameters#setGpsLatitude/setGpsLongitude/setGpsAltitudeメソッドで, GPS情報を設定する.
    • Camera#setParametersメソッドで, Camera.Parametersを設定する.
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.Size;
import android.location.Location;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraView extends SurfaceView
    implements SurfaceHolder.Callback, PictureCallback {
  private Camera mCamera = null;
  private Location mLocation;
  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); // API Level 11で廃止予定に
    // 保存用フォルダ作成
    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) {
      if (mLocation != null) {
        // パラメータ取得
        Camera.Parameters params = mCamera.getParameters();
        // GPS情報設定
        params.setGpsLatitude(mLocation.getLatitude());
        params.setGpsLongitude(mLocation.getLongitude());
        params.setGpsAltitude(mLocation.getAltitude());
        params.setGpsTimestamp(System.currentTimeMillis());
        // パラメータ設定
        mCamera.setParameters(params);
      }
      // シャッターを切る
      mCamera.takePicture(null, null, this);
    }
    return true;
  }

  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    mCamera = Camera.open();
    // パラメータ取得
    Camera.Parameters params = mCamera.getParameters();
    // サイズ:640x480に設定
    params.setPictureSize(640, 480);
    // パラメータ設定
    mCamera.setParameters(params);
    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;
  }

  public void setLocation(Location location) {
    mLocation = location;
  }
}
  • 動作例
端末:SHARP SHL-22 / Android 4.2.2

1) 撮影した写真


2) 写真の属性