Android 调用摄像头功能【拍照】

应用场景:

在Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用。

知识点介绍:

使用权限:调用手机自身设备功能(摄像头拍照功能),应该确保已经在AndroidManifest.xml中正确声明了对摄像头的使用及其它相关的feature。

<!--摄像头权限 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <!--存储权限                    SD卡读写权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--Camera Feature 声明对camera feature的使用 -->
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false" />
    <!--视频、录音权限                   请求音频捕获权限 -->
    <uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
Class类:

1、 SurfaceView
视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
2、 SurfaceHolder
SurfaceHolder是控制surface的一个抽象接口,你可以通过SurfaceHolder来控制surface的尺寸和格式,或者修改surface的像素,监视surface的变化等等,SurfaceHolder是SurfaceView的典型接口。
3、 SurfaceHolder.Callback
用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时,  它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。设置Callback的方法是SurfaceHolder.addCallback。

使用方式:

第一步:
新建一个Android项目CameraTest,包含两个Activity: MainActivity、CameraActivity。
第二步:

【activity_main.xml】

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:background="#FFFFFF"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
    <LinearLayout android:layout_height="wrap_content"
        android:layout_width="match_parent">
        <ImageView 
            android:id="@+id/main_image"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher"
        	android:layout_width="match_parent"/>
    </LinearLayout>
    <LinearLayout 
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="20dp"
        android:orientation="horizontal">
        <Button android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/main_camera"
            android:text="拍照"/>
        <Button android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="退出"
            android:id="@+id/main_quit"/>
    </LinearLayout>
</RelativeLayout>

【MainActivity.java】

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private Button cameraButton;  //拍照按钮
	private Button quitButton;    //退出按钮
	private ImageView imageView;  //图片显示
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initViews();
	}
	
	private void initViews() {
		imageView = (ImageView) findViewById(R.id.main_image);
//		从本地取图片(在sdcard中获取文件)
		Bitmap bitmap = getLoacalBitmap("/sdcard/mhc.jpg"); 
		Log.e("msgTag", new File("/sdcard/mhc.jpg").exists()+"==========");
		imageView .setImageBitmap(bitmap); //设置Bitmap
		cameraButton = (Button) findViewById(R.id.main_camera);
		quitButton = (Button) findViewById(R.id.main_quit);
		MainOnClickListener mainOnClickListener = new MainOnClickListener();
		cameraButton.setOnClickListener(mainOnClickListener);
		quitButton.setOnClickListener(mainOnClickListener);
	}
	
	private  class MainOnClickListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.main_camera:
				startActivity(new Intent(MainActivity.this, CameraActivity.class));
				break;
			case R.id.main_quit:
				MainActivity.this.finish();
				break;
			default:
				break;
			}
		}
	}
	
	/**
	 * 根据文件路径获取所需要文件,并将该文件封装成Bitmap对象返回
	 * @param fileUrl
	 * @return
	 */
	public static Bitmap getLoacalBitmap(String fileUrl) {
        try {
             FileInputStream fis = new FileInputStream(fileUrl);
             return BitmapFactory.decodeStream(fis);  ///把流转化为Bitmap图片        
          } catch (FileNotFoundException e) {
             e.printStackTrace();
             return null;
        }
   }
}
【activity_camera.xml】

<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="#FFFFFF"
    tools:context=".CameraActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <SurfaceView
            android:id="@+id/camera_preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical|center_horizontal" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">
        <Button
            android:id="@+id/camera_save"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="拍照" />
    </LinearLayout>
</RelativeLayout>

【CameraActivity.java】

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class CameraActivity extends Activity {
	private String tag ="CameraActivity";
	private SurfaceView surfaceView; 
	//Surface的控制器
	private SurfaceHolder surfaceHolder;
	private Camera camera;
	private Button saveButton;
	//拍照的回调接口
	private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
		public void onPictureTaken(byte[] data, Camera camera) {
			new SavePictureTask().execute(data);
			camera.startPreview();
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_camera);
		initViews();
	}

	private void initViews() {
		saveButton = (Button) findViewById(R.id.camera_save);
		surfaceView = (SurfaceView) findViewById(R.id.camera_preview);
		surfaceHolder = surfaceView.getHolder();
		// 给SurfaceView当前的持有者  SurfaceHolder 一个回调对象。
		//用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时, 
		//它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。
		//设置Callback的方法是SurfaceHolder.addCallback.
		//实现过程一般继承SurfaceView并实现SurfaceHolder.Callback接口
		surfaceHolder.addCallback(surfaceCallback);
		// 设置surface不需要自己的维护缓存区  
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		saveButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				camera.takePicture(null, null, pictureCallback);
//				Camera.takePicture(shutterCallback,rawCallback,pictureCallback ); 
//				  private ShutterCallback shutterCallback = new ShutterCallback(){  
//				            public void onShutter(){  
//				              /* 按快门瞬间会执行这里的代码 */
//				            }  
//				          };
//				  private PictureCallback rawCallback = new PictureCallback(){  
//				            public void onPictureTaken(byte[] _data, Camera _camera){  
//				              /* 如需要处理 raw 则在这里 写代码 */
//				            }  
//				          };
//				     //当拍照后 存储JPG文件到 sd卡
//				    PictureCallback pictureCallback=new PictureCallback(){
//				        public void onPictureTaken(byte[] data,Camera camera) {
//				            FileOutputStream outSteam=null;
//				            try{
//				                SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss");
//				                String times=format.format((new Date()));
//				                outSteam=new FileOutputStream("/sdcard/"+times+"mhc.jpg");
//				                outSteam.write(data);
//				                outSteam.close();
//				            }catch(FileNotFoundException e){
//				                Log.d("Camera", "row");
//				            } catch (IOException e) {
//				                e.printStackTrace();
//				            }
//				        };
//				    };
			}
		});
	}
	
	
	//SurfaceView当前的持有者的回调接口的实现  
	SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
		
		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			camera = Camera.open();
			Log.e(tag, "摄像头Open完成");
			try {
				camera.setPreviewDisplay(holder);
			} catch (IOException e) {
				camera.release();
				camera = null;
			}
		}
		
		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			Camera.Parameters parameters = camera.getParameters();
			parameters.setPictureFormat(ImageFormat.JPEG);
			camera.setDisplayOrientation(0);
			camera.setParameters(parameters);
			camera.startPreview();
		}
		
		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			camera.stopPreview();
			camera.release();
			camera = null;
		}
	};
	
	class SavePictureTask extends AsyncTask<byte[], String, String> {
		@Override
		protected String doInBackground(byte[]... params) {
			File picture = new File("/sdcard/mhc.jpg");
			try {
				FileOutputStream fos = new FileOutputStream(picture.getPath());
				fos.write(params[0]);
				fos.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			Log.e(tag, "照片保存完成");
			CameraActivity.this.finish();
			return null;
		}
	}
}

下载地址:

http://download.csdn.net/detail/ma_hoking/7297039



你可能感兴趣的:(android,callback,Camera,Surface,摄像头)