並加入自動對焦與列出照片並可刪除該照片檔案
1.AndroidManifest.xml加入權限
2.建立java檔與layout檔
TakeAPhotoActivity.java 拍照
package tw.android;
import android.app.Activity;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
public class TakeAPhotoActivity extends Activity {
private static final String TAG = "TakeAPhotoActivity";
private SurfaceView sv;
// private ImageView iv;
private Button takePhotoBtn, hidePhotoBtn, autoFocus,picList;
// 相機 callback
private CameraCallback cc;
// 快門 callback
private ShCallback sc;
// 處理 raw data callback
private RawCallback rc;
// 處理 jpg callback
private JpgCallback jc;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.take_a_photo_activity);
this.sv = (SurfaceView) this.findViewById(R.id.sv);
this.takePhotoBtn = (Button) this.findViewById(R.id.takePhotoBtn);
this.hidePhotoBtn = (Button) this.findViewById(R.id.hidePhotoBtn);
this.autoFocus = (Button) this.findViewById(R.id.autoFocus);
this.picList= (Button) this.findViewById(R.id.picList);
this.cc = new CameraCallback();
this.sc = new ShCallback();
this.rc = new RawCallback();
this.jc = new JpgCallback(this);
Log.d(TAG, "設定預覽視窗...");
SurfaceHolder sh = this.sv.getHolder();
sh.addCallback(this.cc);
sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Log.d(TAG, "設定拍照頁面...");
this.hidePhotoBtn.setVisibility(View.GONE);
// 按鈕外按自動對焦
autoFocus.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
cc.getCarema().autoFocus(new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
}
});
}
});
//前往照片列表
picList.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
goToPicList();
}
});
}
public void takePhoto(View v) {
Log.d(TAG, "拍照...");
// 需要三個 callback:快門、處理 raw data、處理 jpg
// 拍照時自動對焦
this.cc.getCarema().autoFocus(new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
camera.takePicture(sc, rc, jc);
}
}
});
}
public void hidePhoto(View v) {
Log.d(TAG, "設定拍照頁面...");
this.takePhotoBtn.setVisibility(View.VISIBLE);// 顯示拍照按鈕
this.hidePhotoBtn.setVisibility(View.GONE); // 隱藏重拍按鈕
Log.d(TAG, "回到拍照功能,需重新啟動預覽...");
this.cc.getCarema().startPreview();
}
public void showPhoto(String picPath) {
Log.d(TAG, "取得照片路徑:" + picPath);
Log.d(TAG, "設定照片頁面...");
this.takePhotoBtn.setVisibility(View.GONE);
this.hidePhotoBtn.setVisibility(View.VISIBLE);
}
//前往照片列表
public void goToPicList(){
Intent intent=new Intent(this,PhotoList.class);
startActivity(intent);
}
}
CameraCallback.java
package tw.android;
import java.io.IOException;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
public class CameraCallback implements Callback {
private static final String TAG = "CameraCallback";
private Camera carema;
public Camera getCarema() {
return this.carema;
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "啟動相機...");
this.carema = Camera.open();
try {
Log.d(TAG, "設定預覽視窗");
this.carema.setPreviewDisplay(holder);
}
catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d(TAG, "開始預覽...");
this.carema.setDisplayOrientation(90); //相機旋轉90度
this.carema.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "停止預覽...");
this.carema.stopPreview();
Log.d(TAG, "釋放相機資源...");
this.carema.release();
this.carema = null;
}
}
JpgCallback.java
package tw.android;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Environment;
import android.util.Log;
public class JpgCallback implements PictureCallback {
private static final String TAG = "JpgCallback";
private String picPath;
private TakeAPhotoActivity act;
int number;
public JpgCallback(TakeAPhotoActivity act) {
super();
this.act = act;
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "處理 JPG 資料,輸出 jpg 檔...");
/*-- 2015-09-11 相機旋轉90度後,照片需要跟著旋轉90度 --*/
Bitmap srcBmp, dstBmp;
srcBmp= BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix=new Matrix();
matrix.reset();
matrix.postRotate(90f);
dstBmp= Bitmap.createBitmap(srcBmp, 0, 0, srcBmp.getWidth(), srcBmp.getHeight(), matrix, true);
/*-- 2015-09-11 --*/
FileOutputStream os = null;
try {
File pic = this.createPicFile();
os = new FileOutputStream(pic);
dstBmp.compress(Bitmap.CompressFormat.JPEG, 100, os); //2015-09-11 Bitmap 轉回 byte[]
os.write(data);
}
catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
}
finally {
if (os != null) {
try {
os.close();
}
catch (IOException e) {
}
}
}
Log.d(TAG, "輸出 JPG 完成");
// 顯示照片
this.act.showPhoto(this.picPath);
}
@SuppressLint("DefaultLocale")
private File createPicFile() {
File sdDir = Environment.getExternalStorageDirectory();
Log.d(TAG, "sdDir" + sdDir);
File picDir = new File(sdDir, "takePic"); //建立放置照片資料夾
if (!picDir.exists()) {
picDir.mkdir();
}
long ctm =System.currentTimeMillis(); //照片名
/* SharedPreferences */
try {
SharedPreferences preferencesGet = this.act
.getSharedPreferences("takePic",
android.content.Context.MODE_PRIVATE);
number=preferencesGet.getInt("number", 0); //照片數量
} catch (Exception e) {
}
SharedPreferences preferencesSave = this.act
.getSharedPreferences("takePic",
android.content.Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferencesSave.edit();
Log.d(TAG,number+"");
number++; //照片數量+1
editor.putInt("number", number);
editor.putLong(Integer.toString(number), ctm); //儲存照片名
editor.commit();
String fileName = String.format("%d.jpg", ctm);
File pic = new File(picDir, fileName);
this.picPath = pic.getAbsolutePath();
Log.d(TAG, "照片路徑:" + this.picPath);
return pic;
}
}
RawCallback.java
package tw.android;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.util.Log;
public class RawCallback implements PictureCallback {
private static final String TAG = "RawCallback";
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "處理 Raw data...");
}
}
ShCallback.java
package tw.android;
import android.hardware.Camera.ShutterCallback;
import android.util.Log;
public class ShCallback implements ShutterCallback {
private static final String TAG = "ShCallback";
@Override
public void onShutter() {
Log.d(TAG, "啟動快門...");
}
}
PhotoList.java 列出照片
package tw.android;
import java.io.File;
import android.app.Activity;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
public class PhotoList extends Activity {
private Button[] detelPic;
private String[] dataName;
private int number;
private int id;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.photo_list);
setTable();
}
// 排版
public void setTable() {
try {
SharedPreferences preferencesGet = getApplicationContext()
.getSharedPreferences("takePic",
android.content.Context.MODE_PRIVATE);
number=preferencesGet.getInt("number", 0);//取出照片數量
dataName = new String[number];
Log.i("number", number+"");
for(int i = 0; i < number; i++){
dataName[i]=String.valueOf(preferencesGet.getLong(Integer.toString(i+1), 0)); //放入照片名稱
Log.i("dataName[i]", dataName[i]+"");
}
} catch (Exception e) {
}
TableLayout t1 = (TableLayout) findViewById(R.id.tableSet);
t1.removeAllViews();
TableRow.LayoutParams tP = new TableRow.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f);
tP.setMargins(0, 0, 0, 20);
detelPic = new Button[number];
for (int i = 0; i < number; i++) { // 列
TableRow row = new TableRow(this);
ImageView iv = new ImageView(this);
String picPath = "/storage/emulated/0/takePic/" + dataName[i]
+ ".jpg";
Uri uri = Uri.fromFile(new File(picPath));
iv.setLayoutParams(tP);
iv.setImageURI(uri);
row.addView(iv, 0);
// 刪除button
detelPic[i] = new Button(this);
detelPic[i].setText("刪除");
detelPic[i].setId(i);
detelPic[i].setOnClickListener(dp); // 動作
row.addView(detelPic[i], 1);
t1.addView(row);
}
}
private OnClickListener dp = new OnClickListener() {
public void onClick(View v) {
id = v.getId();
// 刪除照片
File file = new File("/storage/emulated/0/takePic/" + dataName[id]
+ ".jpg");
file.delete();
setTable();//重整
}
};
}
take_a_photo_activity.xml //拍照layout
photo_list.xml //照相列表 layout
檔案下載:
https://github.com/terryyamg/AndroidCamera
參考來源:
1.http://cw1057.blogspot.tw/2011/12/android-camera_09.html
2.http://stackoverflow.com/questions/8058122/where-to-put-autofocus-in-the-class-android-camera
3.http://stackoverflow.com/questions/5486529/delete-file-from-internal-storage
4.http://stackoverflow.com/questions/10660598/android-camera-preview-orientation-in-portrait-mode
(2015-09-11 update)
5. http://rincliu.com/blog/2013/11/18/camera/
6.http://bingtian.iteye.com/blog/642128


















