android前后摄像头切换demo,startview后的页面上有切换、拍照两个按钮,拍照后照片未保存,需要保存的请看下方注释,实现了拍照、聚焦功能,以下是CameraPreview.java源码:


package com.myselftest;


import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.List;


import android.content.Context;

import android.hardware.Camera;

import android.hardware.Camera.Size;

import android.os.Bundle;

import android.util.Log;

import android.view.Display;

import android.view.KeyEvent;

import android.view.Surface;

import android.view.SurfaceHolder;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import android.widget.TextView;

import android.widget.Toast;

import android.os.Handler;

import android.os.Message;

import android.widget.RelativeLayout;

import android.view.MotionEvent;

import android.app.Activity;

import android.view.View.OnClickListener;

import android.hardware.Camera.CameraInfo;

import android.os.SystemProperties;

import android.view.View.OnTouchListener;

import android.graphics.Rect;

import android.hardware.Camera.PictureCallback;


public class CameraPreview extends Activity implements OnClickListener, SurfaceHolder.Callback {


   private static final String TAG = "CameraPreview";

    private Camera mCamera;

    private Camera.Parameters mCameraParam;

    private int mPrvW = 800;

    private int mPrvH = 600;


    private final AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback();


    private long mFocusCallbackTime;

    private FocusIndicatorView mFocusIndicatorView;

    private static final int WIDTH_DP = 80;

    private static final int HEIGTH_DP = 80;

    private boolean focusing = false;

    private boolean state;

    

    private TextView btn_position = null;

    private TextView btn_capture = null;

    private SurfaceHolder holder = null;

    private VideoPreview mVideoPreview;

    private int cameraPosition = 1; //1,camera_back 0,camera_front

    private int cameraId;

    private  RelativeLayout mRelativeLayout;

    CameraInfo ci = null;

    

    public static int dip2px(Context context, float dpValue) {   

        final float scale = context.getResources().getDisplayMetrics().density;   

        return (int) (dpValue * scale + 0.5f);

    }

    

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        // TODO Auto-generated method stub

        super.onCreate(savedInstanceState);


        setContentView(R.layout.camera_preview);


        Window win = getWindow();

        win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);


        btn_position  = (TextView) findViewById(R.id.btn_position);

        btn_capture = (TextView) findViewById(R.id.btn_capture);

        mPrvW = this.getWindow().getWindowManager().getDefaultDisplay().getWidth();

        mPrvH = mPrvW*4/3;

        mFocusIndicatorView = new FocusIndicatorView(this);

        int width_px = dip2px(this, WIDTH_DP);

        int heigth_px = dip2px(this, HEIGTH_DP);

        RelativeLayout.LayoutParams mLayoutParams = new             RelativeLayout.LayoutParams(width_px, heigth_px);

        int[] rules = mLayoutParams.getRules();

        rules[RelativeLayout.CENTER_IN_PARENT] = 1;

        mRelativeLayout = (RelativeLayout) findViewById(R.id.main_layout);

        mRelativeLayout.addView(mFocusIndicatorView, mLayoutParams);

        mRelativeLayout.setOnTouchListener(onTouchListener);

        mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview);

        

        btn_position.setOnClickListener(this);

        btn_capture.setOnClickListener(this);

    }


    @Override

public void onClick(View v){

if(v.equals(btn_position)){

camera_position();

}else if(v.equals(btn_capture)){

rawCapture();

}

}

    

    @Override

    protected void onResume() {

        super.onResume();

        

        mVideoPreview.setAspectRatio(mPrvW, mPrvH);

        holder = mVideoPreview.getHolder();

        holder.addCallback(this);

        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


    }


    public boolean onTouchEvent(MotionEvent event) {

        if(focusing == false) {

            focusing = true;

            mFocusIndicatorView.showStart();

            mCamera.autoFocus(mAutoFocusCallback);

        }

        return true;

    }

    

    public class FocusIndicatorView extends View {

        public FocusIndicatorView(Context context) {

            super(context);

        }

    private void setDrawable(int resid) {

        setBackgroundDrawable(getResources().getDrawable(resid));

    }



    public void showStart() {

        setDrawable(R.drawable.ic_focus_focusing);

    }



    public void showSuccess() {

        setDrawable(R.drawable.ic_focus_focused);

    }



    public void showFail() {

        setDrawable(R.drawable.ic_focus_failed);

    }



    public void clear() {

        setBackgroundDrawable(null);

    }

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        Log.i(TAG, "surfaceChanged width is : " + width+" height is"+height+" ci.orientation="+ci.orientation);

        startPreview(ci.orientation);

    }


    public void surfaceCreated(SurfaceHolder holder) {

        // TODO Auto-generated method stub

    ci = new CameraInfo();

    Camera.getCameraInfo(0, ci);

        openCamera(0);

        cameraId = 0;

        try {

            mCamera.setPreviewDisplay(holder);

        } catch (IOException exception) {

            closeCamera();

            Log.i(TAG, "surfaceCreated closeCamera ");

        }


    }


    private void openCamera(int cmaId) {

        if (mCamera == null) {

            mCamera = Camera.open(cmaId);

            cameraId = cmaId;

            Log.i(TAG, "Enter openCamera to init the mCamera.");

            if (null == mCamera) {

                Log.i(TAG, "init the mCamera is null.");

            }

        }

    }


    private void closeCamera() {

        if (null != mCamera) {

            mCamera.release();

            mCamera = null;

        }

    }


    public void surfaceDestroyed(SurfaceHolder holder) {

        // TODO Auto-generated method stub

        stopPreview();

        closeCamera();

        Log.i(TAG, "surfaceDestroyed closeCamera ");


    }


    private void stopPreview() {

        if (null != mCamera) {

            mCamera.stopPreview();

        }

    }


    private Handler mHandler = new Handler() {

    @Override

        public void handleMessage(Message msg) {

            // TODO Auto-generated method stub

            super.handleMessage(msg);

            if (0 == msg.what) {

               mFocusIndicatorView.clear();

            }

        }

    };

    

    private void startPreview(int orientation) {//orientation:当前所选摄像头的偏转角度

    if (null != mCamera) {

    mCameraParam = mCamera.getParameters();

    }else{

    return;

    }

        Size size = mCameraParam.getPictureSize();

        List sizes = mCameraParam.getSupportedPreviewSizes();

        Size optimalSize = null;

        if (size != null && size.height != 0) {

            optimalSize = getOptimalPreviewSize(sizes, (double) mPrvH / mPrvW);

        }

        if (optimalSize != null) {

            mCameraParam.setPreviewSize(optimalSize.width, optimalSize.height);

        } else {

            mCameraParam.setPreviewSize(mPrvW, mPrvH);

        }

        mCameraParam.set("fps-mode", 0); // Frame rate is normal

        mCameraParam.set("cam-mode", 0); // Cam mode is preview

        if (cameraPosition == 1) {

            mCameraParam.setFocusMode(mCameraParam.FOCUS_MODE_CONTINUOUS_PICTURE);

            mCameraParam.setFlashMode(Camera.Parameters.FLASH_MODE_ON);  

        }

        mCamera.setDisplayOrientation(orientation);

        mCamera.setParameters(mCameraParam);

        

        mCamera.startPreview();

        mCamera.autoFocus(mAutoFocusCallback);

    }


    private Size getOptimalPreviewSize(List sizes, double targetRatio) {

        final double ASPECT_TOLERANCE = 0.05;

        if (sizes == null) {

            return null;

        }


        Size optimalSize = null;

        double minDiff = Double.MAX_VALUE;


        Display display = getWindowManager().getDefaultDisplay();

        int targetHeight = Math.min(display.getHeight(), display.getWidth());


        if (targetHeight <= 0) {

            WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

            targetHeight = windowManager.getDefaultDisplay().getHeight();

        }


        Log.d(TAG, "getOptimalPreviewSize() sizes.size = " + sizes.size());

        int i = 1;

        for (Size size : sizes) {

            double ratio = (double) size.width / size.height;

            i++;

            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {

                continue;

            }

            if (Math.abs(size.height - targetHeight) < minDiff) {

                optimalSize = size;

                minDiff = Math.abs(size.height - targetHeight);

            }

        }


        if (optimalSize == null) {

            Log.d(TAG, "No preview size match the aspect ratio");

            minDiff = Double.MAX_VALUE;

            for (Size size : sizes) {

                if (Math.abs(size.height - targetHeight) < minDiff) {

                    optimalSize = size;

                    minDiff = Math.abs(size.height - targetHeight);

                }

            }

        } else {

            Log.d(TAG, String.format("Optimal preview size is %sx%s", optimalSize.width, optimalSize.height));

        }

        return optimalSize;

    }


    @Override

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        switch (keyCode) {

        case KeyEvent.KEYCODE_DPAD_CENTER:

            return true;

        case KeyEvent.KEYCODE_SEARCH:

            return true;

        case KeyEvent.KEYCODE_FOCUS:

            return true;

        case KeyEvent.KEYCODE_BACK:

            break;

        }

        return super.onKeyDown(keyCode, event);

    }

    

    private void camera_position(){

    CameraInfo cameraInfo = new CameraInfo();

    int cameraCount = Camera.getNumberOfCameras();

    for(int i = 0; i

    Camera.getCameraInfo(i, cameraInfo);

    Log.d(TAG, "cameraOrientation-"+i+":"+cameraInfo.orientation);

if(cameraPosition == 0){

   if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK){

   stopPreview();

   closeCamera();

   openCamera(i);

   cameraPosition = 1;

   if (null != mCamera) {

   try {

                   mCamera.setPreviewDisplay(holder);

               } catch (IOException ex) {

                   closeCamera();

                   Log.i(TAG, "camera_position closeCamera "+i);

                   ex.printStackTrace();

               }

   startPreview(cameraInfo.orientation);

   }

   break;

   }

   }else{

   if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){

   stopPreview();

   closeCamera();

   openCamera(i);

   cameraPosition = 0;

   if (null != mCamera) {

   try {

                   mCamera.setPreviewDisplay(holder);

               } catch (IOException ex) {

                   closeCamera();

                   Log.i(TAG, "camera_position closeCamera "+i);

                   ex.printStackTrace();

               }

   startPreview(90);

   }

   break;

   }

   }

    }

    }


    private void rawCapture() {

        if(mCamera != null){

            try {

           mCamera.startPreview();

           mCamera.autoFocus(mAutoFocusCallback);

           mCamera.takePicture(null, null,  new JpegPictureCallback());

           Toast.makeText(this, getString(R.string.cma_capture_success), Toast.LENGTH_LONG).show();

           mCamera.stopPreview();

           mCamera.setPreviewDisplay(holder);

           mCamera.startPreview();

       }catch(Exception ex){

       closeCamera();

       ex.printStackTrace();

       }

Log.i(TAG, "rawCapture function end");           

        }

    }


    private final class AutoFocusCallback implements android.hardware.Camera.AutoFocusCallback {

        public void onAutoFocus(boolean focused, android.hardware.Camera camera) {

            mFocusCallbackTime = System.currentTimeMillis();

            Log.i(TAG, "mFocusCallbackTime is " + mFocusCallbackTime);

            if(focused && !state) {

                mFocusIndicatorView.showSuccess();

                mHandler.sendEmptyMessageDelayed(0, 1500);

            } else if(!focused){

                mHandler.removeMessages(0);

                mFocusIndicatorView.showFail();

            }

            

            focusing =  false;

            state = focused;

        }

    }


    private final class JpegPictureCallback implements PictureCallback {

        public void onPictureTaken(byte[] jpegData, android.hardware.Camera camera) {

            Log.d(TAG, "mJpegPictureCallbackTime = " + System.currentTimeMillis());

            if (jpegData != null) {

                storeImage(jpegData);

            }

        }

    }

    

    private void storeImage(byte[] jpegData) {//本例未保存所拍照片,如需要保存,请取消下方的注释

        String name = "factorymode_test.jpg";


//        File fHandle = new File(name);

//        try {

//            OutputStream bos = new FileOutputStream(fHandle);

//            bos.write(jpegData);

//            bos.close();

//            long storeImageTime = System.currentTimeMillis();

//            Log.d(TAG, "storeImageTime = " + storeImageTime);

//        } catch (Exception ex) {

//            fHandle.delete();

//        }

    }

    

    OnTouchListener onTouchListener = new OnTouchListener(){

   

    @Override

    public boolean onTouch(View v, MotionEvent event){

    mFocusIndicatorView.setX(event.getX());

mFocusIndicatorView.setY(event.getY());

    if(event.getAction() == MotionEvent.ACTION_DOWN){

    mFocusIndicatorView.showSuccess();

    }else if(event.getAction() == MotionEvent.ACTION_UP){

    mFocusIndicatorView.showFail();

    if(cameraPosition == 1){

    focusOnTouch(event);

    }

    }

   

    return true;

    }

    };

    

    private void focusOnTouch(MotionEvent event){

    int [] location = new int[2];

    mRelativeLayout.getLocationOnScreen(location);

   

    Rect focusRect = calculateTapArea(mVideoPreview.getWidth(), mVideoPreview.getHeight(), 1f, event.getRawX(), 

    event.getRawY(), location[0], location[0] + mRelativeLayout.getWidth(), location[1], location[1] + mRelativeLayout.getHeight());

    Rect meteringRect = calculateTapArea(mVideoPreview.getWidth(), mVideoPreview.getHeight(), 1.5f, event.getRawX(), 

event.getRawY(), location[0], location[0] + mRelativeLayout.getWidth(), location[1], location[1] + mRelativeLayout.getHeight());

    mCameraParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

    if(mCameraParam.getMaxNumFocusAreas() > 0){

    List focusAreas = new ArrayList();

    focusAreas.add(new Camera.Area(focusRect,  1000));    

    mCameraParam.setFocusAreas(focusAreas);

    }

   

    if(mCameraParam.getMaxNumMeteringAreas() > 0){

    List meteringAreas = new ArrayList();

    meteringAreas.add(new Camera.Area(meteringRect,  1000));    

    mCameraParam.setMeteringAreas(meteringAreas);

    }

    if(mCamera != null){

    mCamera.setParameters(mCameraParam);

    }

    mCamera.autoFocus(mAutoFocusCallback);

    }

    

    private Rect calculateTapArea(int focusWidth, int focusHeight, float areaMultiple, float x, float y, int previewLeft, int previewRight, int preViewTop, int preViewBottom){

    int areaWidth = (int)(focusWidth * areaMultiple);

    int areaHeight = (int)(focusHeight * areaMultiple);

    int centerX = (previewLeft + previewRight) / 2;

    int centerY = (preViewTop + preViewBottom) / 2;

    double unitx = (((double)previewRight - (double)previewLeft)) /2000;

    double unity = (((double)preViewBottom - (double)preViewTop)) /2000;

    int left = clamp((int)(((x - areaWidth / 2) - centerX) / unitx),  -1000, 1000);

    int top = clamp((int)(((y - areaHeight / 2) - centerY) / unity),  -1000, 1000);

    int right = clamp((int)(left + areaWidth / unitx),  -1000, 1000);

    int bottom = clamp((int)(top + areaHeight / unity),  -1000, 1000);

   

    return new Rect(left, top, right, bottom);

    }

    

    private int clamp(int x, int min, int max){

    if(x > max){

    return max;

    }

    if(x < min){

    return min;

    }

    return x;

    }

    

}


camera_preview.xml布局文件:


<?xml version="1.0" encoding="utf-8"?>

  xmlns:android="http://schemas.android.com/apk/res/android"

  android:layout_width="fill_parent"

  android:layout_height="fill_parent"

  android:id="@+id/main_layout" 

  android:orientation="vertical">

  

 

  android:id="@+id/camera_preview" 

  android:layout_width="fill_parent" 

  android:layout_height="fill_parent" 

  android:layout_centerInParent="true"/>

  

 

     android:id="@+id/btn_capture"

     android:layout_width="wrap_content"

     android:layout_height="wrap_content"

     android:layout_alignParentBottom="true"

     android:layout_alignParentRight="true"

     android:layout_marginRight="33dp"

     android:gravity="center"

     android:text="@string/cma_capture" />


 

     android:id="@+id/btn_position"

     android:layout_width="wrap_content"

     android:layout_height="wrap_content"

     android:layout_alignParentBottom="true"

     android:layout_alignParentLeft="true"

     android:layout_marginLeft="48dp"

     android:gravity="center"

     android:text="@string/cma_position" />


以上代码在android6.0上测试通过。

更多相关文章

  1. Eclipse Android(安卓)SDK Manager下载失败解决
  2. Android(安卓)Studio Gradle Connection reset
  3. Android调用系统摄像头拍照并剪裁压缩
  4. Android联系人读取操作笔记
  5. Android写Logcat文件保存到SD卡
  6. android 文件存储注意点
  7. Android创建菜单栏(android布局实现)
  8. Android拍照、录像、录音代码范例
  9. android调用系统相机并调整照片大小保存,最后上传照片

随机推荐

  1. Android(安卓)中文 API (93) —— BaseExpa
  2. Myeclispe10+ Android4.4 环境搭建
  3. 边缘图片android布局属性详解
  4. Eclipse / Android(安卓): “Errors runn
  5. Android(安卓)XML解析
  6. Android(安卓)Dialog无法去除遮罩
  7. Android取消EditText自动获取焦点默认行
  8. androdi ImageView.ScaleType
  9. Android(安卓)TextView 设置中划线 下划
  10. Android横竖屏限制切换