Androidカスタムカメラカウントダウン写真


カスタマイズした写真はSurfaceViewコントロールで写真のプレビュー領域を表示します。以下はレイアウトファイルです。
二つのTextViewは、提示情報とカウントダウンの秒数を表示するためのものです。
関連教程:Androidは、カメラやアルバムから画像を切り取るために開発しました。
Androidはカメラを起動して写真を撮って写真に戻ります。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#266194"
 android:orientation="vertical"
 tools:context=".TestActivity" >
 <SurfaceView
 android:id="@+id/surfaceView"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_centerInParent="true" />
 <LinearLayout
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerInParent="true"
 android:orientation="vertical" >
 <TextView
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="         "
 android:textColor="#ff0000"
 android:textSize="32sp" />
 <TextView
 android:id="@+id/tv_time"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:paddingTop="10dp"
 android:gravity="center_horizontal"
 android:textColor="#266194"
 android:textSize="32sp" />
 </LinearLayout>
</RelativeLayout> 
続いて、manActivityでの具体的な実現と詳細なコメントです。

package com.dhsr.pujiejia.ui;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import com.example.pujiejiaapp.R;
@SuppressLint({ "NewApi", "SdCardPath" })
public class CameraActivity extends Activity implements Runnable {
 //       
 private SurfaceView surfaceView;
 private TextView tv_time;
 //      
 private int cameratime = 4;
 private Camera camera;
 private boolean preview = false;
 //     
 private String filename;
 //           
 private String timeString;
 //      
 private SimpleDateFormat dateFormat;
 //     
 private Date date;
 //     
 boolean stopThread = false;
 private File file;
 String photo;
 private Handler mHandler = new Handler() {
 public void handleMessage(android.os.Message msg) {
 int what = msg.what;
 switch (what) {
 case 222:
 tv_time.setText("" + cameratime);
 if ("0".equals(tv_time.getText().toString())) {
  tv_time.setText("    !");
  takePhoto();
 }
 break;
 }
 };
 };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_test);
 CameraActivity.this.setFinishOnTouchOutside(false);
 //      
 findView();
 surfaceView.getHolder().addCallback(new SufaceListener());
 /*     Surface         ,                      */
 surfaceView.getHolder()
 .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 surfaceView.getHolder().setFixedSize(200, 200); //      
 }
 @Override
 protected void onStart() {
 // TODO Auto-generated method stub
 super.onStart();
 //     
 new Thread(this).start();
 }
 private final class SufaceListener implements SurfaceHolder.Callback {
 /**
 * surface  
 */
 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
 int height) {
 }
 /**
 * surface  
 */
 @Override
 public void surfaceCreated(SurfaceHolder holder) {
 try {
 for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
  CameraInfo info = new CameraInfo();
  Camera.getCameraInfo(i, info);
  //           
  if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
  camera = Camera.open(i);
  }
 }
 Camera.Parameters parameters = camera.getParameters();
 /*         5   , */
 parameters.setPreviewFrameRate(5);
 /*          :jpg */
 parameters.setPictureFormat(PixelFormat.JPEG);
 /*      */
 parameters.set("jpeg-quality", 85);
 WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
 camera.setParameters(parameters);
 camera.setPreviewDisplay(surfaceView.getHolder());//   SurfaceView      
 camera.startPreview();
 preview = true;
 } catch (Exception e) {
 }
 }
 /**
 * surface  
 */
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
 if (camera != null) {
 if (preview)
  camera.stopPreview();
 camera.release();
 camera = null;
 }
 }
 }
 /**
 *     
 */
 private void takePhoto() {
 //       
 camera.takePicture(null, null, new Camera.PictureCallback() {
 @Override
 public void onPictureTaken(byte[] data, Camera camera) {
 try {
  Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
  data.length);
  timeString = formatDate();
  //   data/data         
  filename = "/data/data/com.example.pujiejiaapp/images/"
  + timeString + ".jpg";
  File file = new File(filename);
  boolean createNewFile = file.createNewFile()
  System.out.println("         " + createNewFile);
  System.out.println(file);
  FileOutputStream outStream = new FileOutputStream(file);
  bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);
  outStream.flush();
  outStream.close();
  //     
  camera.stopPreview();
  camera.startPreview();
  preview = true;
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
 }
 }
 });
 }
 @Override
 public void run() {
 while (!stopThread) {
 try {
 //      
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 cameratime--;
 mHandler.sendEmptyMessage(222);
 if (cameratime <= 0) {
 break;
 }
 }
 }
 //      
 private void findView() {
 surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);
 tv_time = (TextView) findViewById(R.id.tv_time);
 }
 //         
 public String formatDate() {
 date = new Date(System.currentTimeMillis());
 //     
 dateFormat = new SimpleDateFormat("'IMG'_yyyyMMddHHmmss");
 return dateFormat.format(date);
 }
 @Override
 protected void onDestroy() {
 // TODO Auto-generated method stub
 //      
 super.onDestroy();
 stopThread = true;
 }
} 
コアコード詳細:
1.SurfaceViewを作成する場合、surfaceCreated()方法で

for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
  CameraInfo info = new CameraInfo();
  Camera.getCameraInfo(i, info);
  //           
  if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
  camera = Camera.open(i);
  }
 }
この部分のコードはカメラを開ける時に、フロントカメラのCamera Info..FACING_BACKはデフォルトでバックカメラを開きます。FACING_FRONTフロントカメラ
2.写真撮影のタキPhotoo()方法:

Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
  data.length);
  timeString = formatDate();
  filename = "/data/data/com.example.pujiejiaapp/images/"
  + timeString + ".jpg";
  photo = timeString + ".jpg";
  File file = new File(filename);
  boolean createNewFile = file.createNewFile();
  FileOutputStream outStream = new FileOutputStream(file);
  bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);
この部分のコードは、撮影した画像をbitmap形式で指定されたディレクトリに保存します。
3.サブスレッドを開いてカウントダウン撮影に使います。

public void run() {
 while (!stopThread) {
 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 cameratime--;
 mHandler.sendEmptyMessage(222);
 if (cameratime <= 0) {
 break;
 }
 }
 }
コアコードの詳細なコメントをご理解いただき、ご意見をお待ちしております。皆様のご協力をお願いします。ありがとうございます。