当前位置: 代码迷 >> Android >> Android 调用摄像头效能【拍照与视频】
  详细解决方案

Android 调用摄像头效能【拍照与视频】

热度:59   发布时间:2016-04-28 05:23:14.0
Android 调用摄像头功能【拍照与视频】

应用场景:

在Android开发过程中,有时需要调用手机自身设备的功能,上篇文章主要侧重摄像头拍照功能的调用。本篇文章将综合实现拍照与视频的操作。

知识点介绍:

该部分请阅读 【Android 调用摄像头功能】

使用方式:

第一步:

新建一个Android项目CameraPhotoVedio,包含两个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:layout_height="match_parent"    android:background="@drawable/shape_main"    tools:context=".MainActivity" >    <LinearLayout android:layout_height="wrap_content"        android:layout_marginTop="50dp"        android:layout_width="match_parent"        android:orientation="vertical">        <ImageView android:layout_height="wrap_content"            android:layout_width="wrap_content"            android:layout_gravity="center"            android:src="@drawable/main"/>    </LinearLayout>    <LinearLayout android:layout_height="wrap_content"        android:layout_marginTop="100dp"        android:layout_width="match_parent"        android:layout_alignParentBottom="true"        android:orientation="vertical">        <Button            android:id="@+id/main_button"            android:layout_height="50dp"            android:layout_marginBottom="50dp"            android:background="@drawable/shape_main"            android:layout_width="match_parent"            android:textColor="#FFFFFF"            android:text="使用摄像头"/>    </LinearLayout></RelativeLayout>
【MainActivity.java】

import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity {	private Button button; //调用摄像头按钮		@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		initViews();	}	private void initViews() {		button = (Button) findViewById(R.id.main_button);		button.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				startActivity(new Intent(getApplicationContext(), CameraActivity.class));			}		});	}}

【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:background="#FFFFFF"    android:layout_height="match_parent"    tools:context=".CameraActivity" >    <SurfaceView         android:layout_width="match_parent"    	android:layout_height="match_parent"    	android:id="@+id/camera_surfaceview"/>	<TextView android:layout_height="wrap_content"	    android:layout_width="wrap_content"	    android:text="计时区域"	    android:id="@+id/camera_time"/>	<LinearLayout android:layout_height="wrap_content"	    android:layout_width="match_parent"	    android:layout_alignParentBottom="true"	    android:orientation="horizontal">	    <Button android:layout_height="30dp"	        android:layout_width="match_parent"	        android:layout_marginBottom="20dp"	        android:layout_weight="1"	        android:background="@drawable/shape_main"	        android:id="@+id/camera_photo"	        android:layout_marginLeft="5dp"	        android:textColor="#FFFFFF"	        android:layout_marginRight="5dp"	        android:text="照片摄取"/>	    <Button android:layout_height="30dp"	        android:layout_marginBottom="20dp"	        android:layout_width="match_parent"	        android:layout_weight="1"	        android:background="@drawable/shape_main"	        android:id="@+id/camera_vedio"	        android:layout_marginLeft="5dp"	        android:textColor="#FFFFFF"	        android:layout_marginRight="5dp"	        android:text="视频摄取"/>	</LinearLayout></RelativeLayout>

【CameraActivity.java】

import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.Date;import com.example.cameraphotovideo.utils.FormatUtil;import android.graphics.ImageFormat;import android.hardware.Camera;import android.hardware.Camera.PictureCallback;import android.media.MediaRecorder;import android.os.AsyncTask;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.app.Activity;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceHolder.Callback;import android.view.SurfaceView;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class CameraActivity extends Activity {	private String tag ="MaHaochen_______CameraActivity";	private SurfaceView surfaceView;	private SurfaceHolder surfaceHolder;	private Camera camera;	private MediaRecorder mediaRecorder;	private Button photoButton;  //拍照按钮	private Button vedioButton;  //摄像按钮 	private TextView timeTextView;		protected boolean isPreview = false; //摄像区域是否准备良好	private boolean isRecording = true; // true表示没有录像,点击开始;false表示正在录像,点击暂停	private boolean bool;		private int hour = 0;	private int minute = 0;     //计时专用	private int second = 0;		private File mRecVedioPath;	private File mRecAudioFile;		@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_camera);		initCamera();		initViews();	}	//初始化摄像头	private void initCamera() {		mRecVedioPath = new File(Environment.getExternalStorageDirectory()				.getAbsolutePath() + "/mahc/video/temp/");		if (!mRecVedioPath.exists()) {			mRecVedioPath.mkdirs();		}		surfaceView = (SurfaceView) findViewById(R.id.camera_surfaceview);		SurfaceHolder cameraSurfaceHolder = surfaceView.getHolder();		cameraSurfaceHolder.addCallback(new Callback() {						@Override			public void surfaceCreated(SurfaceHolder holder) {				try {				camera = Camera.open();				//设置Camera的角度/方向				camera.setDisplayOrientation(90);				Camera.Parameters parameters = camera.getParameters();				parameters.setPreviewFrameRate(5); // 每秒5帧				parameters.setPictureFormat(ImageFormat.JPEG);// 设置照片的输出格式				parameters.set("jpeg-quality", 85);// 照片质量				camera.setParameters(parameters);				camera.setPreviewDisplay(holder);				isPreview = true;				camera.startPreview();				} catch (IOException e) {					e.printStackTrace();				}				surfaceHolder = holder;			}						@Override			public void surfaceChanged(SurfaceHolder holder, int format, int width,					int height) {				surfaceHolder = holder;			}						@Override			public void surfaceDestroyed(SurfaceHolder holder) {				if (camera != null) {					if (isPreview) {						camera.stopPreview();						isPreview = false;					}					camera.release();					camera = null; // 记得释放Camera				}				surfaceView = null;				surfaceHolder = null;				mediaRecorder = null;			}		});		//开发时建议设置		//This method was deprecated in API level 11. this is ignored, this value is set automatically when needed. 		cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);	}		//初始化视图组件	private void initViews() {		timeTextView = (TextView) findViewById(R.id.camera_time);		timeTextView.setVisibility(View.GONE);		photoButton = (Button) findViewById(R.id.camera_photo);		vedioButton = (Button) findViewById(R.id.camera_vedio);		ButtonOnClickListener onClickListener = new ButtonOnClickListener();		photoButton.setOnClickListener(onClickListener);		vedioButton.setOnClickListener(onClickListener);	}		class ButtonOnClickListener implements OnClickListener{		@Override		public void onClick(View v) {			switch (v.getId()) {			case R.id.camera_vedio:				//点击开始录像				if(isRecording){					if (isPreview) {						camera.stopPreview();						camera.release();						camera = null;					}					second = 0;					minute = 0;					hour = 0;					bool = true;					if(null==mediaRecorder){						mediaRecorder = new MediaRecorder();					}else {						mediaRecorder.reset();					}					//表面设置显示记录媒体(视频)的预览					mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());					//开始捕捉和编码数据到setOutputFile(指定的文件)					mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);					//设置用于录制的音源					mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);					//设置在录制过程中产生的输出文件的格式					mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);					//设置视频编码器,用于录制					mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);					//设置audio的编码格式					mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);					//设置要捕获的视频的宽度和高度					mediaRecorder.setVideoSize(320, 240);					// 设置要捕获的视频帧速率					mediaRecorder.setVideoFrameRate(15);					try {						mRecAudioFile = File.createTempFile("Vedio", ".3gp",								mRecVedioPath);					} catch (IOException e) {						e.printStackTrace();					}					mediaRecorder.setOutputFile(mRecAudioFile.getAbsolutePath());					try {						mediaRecorder.prepare();						timeTextView.setVisibility(View.VISIBLE);						handler.postDelayed(task, 1000);						mediaRecorder.start();					} catch (Exception e) {						e.printStackTrace();					}					isRecording = !isRecording;					Log.e(tag, "=====开始录制视频=====");				}else {					//点击停止录像					bool = false;					mediaRecorder.stop();					timeTextView.setText(FormatUtil.format(hour)+":"+FormatUtil.format(minute)+":"+ FormatUtil.format(second));					mediaRecorder.release();					mediaRecorder = null;					FormatUtil.videoRename(mRecAudioFile);					Log.e(tag, "=====录制完成,已保存=====");					isRecording = !isRecording;					try {						camera = Camera.open();						Camera.Parameters parameters = camera.getParameters();//						parameters.setPreviewFrameRate(5); // 每秒5帧						parameters.setPictureFormat(ImageFormat.JPEG);// 设置照片的输出格式						parameters.set("jpeg-quality", 85);// 照片质量						camera.setParameters(parameters);						camera.setPreviewDisplay(surfaceHolder);						camera.startPreview();						isPreview = true;					} catch (Exception e) {						e.printStackTrace();					}				}				break;			case R.id.camera_photo:				if (mediaRecorder != null) {					try {						bool = false;						mediaRecorder.stop();						timeTextView.setText(FormatUtil.format(hour) + ":" + FormatUtil.format(minute) + ":"								+ FormatUtil.format(second));						mediaRecorder.release();						mediaRecorder = null;						FormatUtil.videoRename(mRecAudioFile);					} catch (Exception e) {						e.printStackTrace();					}					isRecording = !isRecording;					Log.e(tag, "=====录制完成,已保存=====");					try {						camera = Camera.open();						Camera.Parameters parameters = camera.getParameters();//						parameters.setPreviewFrameRate(5); // 每秒5帧						parameters.setPictureFormat(ImageFormat.JPEG);// 设置照片的输出格式						parameters.set("jpeg-quality", 85);// 照片质量						camera.setParameters(parameters);						camera.setPreviewDisplay(surfaceHolder);						camera.startPreview();						isPreview = true;					} catch (Exception e) {						e.printStackTrace();					}				}				if (camera != null) {					camera.autoFocus(null);					camera.takePicture(null, null, new PictureCallback() {						@Override						public void onPictureTaken(byte[] data, Camera camera) {							new SavePictureTask().execute(data);							camera.startPreview();							Log.e(tag,"=====拍照成功=====");						}					}); // 拍照				}				break;			default:				break;			}		}	}	/*	 * 定时器设置,实现计时	 */	private Handler handler = new Handler();	private Runnable task = new Runnable() {		public void run() {			if (bool) {				handler.postDelayed(this, 1000);				second++;				if (second >= 60) {					minute++;					second = second % 60;				}				if (minute >= 60) {					hour++;					minute = minute % 60;				}				timeTextView.setText(FormatUtil.format(hour) + ":" + FormatUtil.format(minute) + ":"						+ FormatUtil.format(second));			}		}	};				class SavePictureTask extends AsyncTask<byte[], String, String> {		@Override		protected String doInBackground(byte[]... params) {			String path = Environment.getExternalStorageDirectory()					.getAbsolutePath() + "/mahc/image";			File out = new File(path);			if (!out.exists()) {				out.mkdirs();			}			File picture = new File(path+"/"+new Date().getTime()+".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;		}	}}

第三步:该项目需要一个工具类FormatUtil.java

import java.io.File;import java.text.SimpleDateFormat;import java.util.Date;import android.os.Environment;public class FormatUtil {	/**	 * 将缓存文件夹的数据转存到vedio文件下	 * @param recAudioFile	 */	public static void videoRename(File recAudioFile) {		String path = Environment.getExternalStorageDirectory()				.getAbsolutePath()+ "/mahc/video/"+ "0" + "/";		String fileName = new SimpleDateFormat("yyyyMMddHHmmss")				.format(new Date()) + ".3gp";		File out = new File(path);		if (!out.exists()) {			out.mkdirs();		}		out = new File(path, fileName);		if (recAudioFile.exists())			recAudioFile.renameTo(out);	}		/**	 * 用以计时操作的相关方法	 * @param num	 * @return	 */	public static String format(int num){		String s = num + "";		if (s.length() == 1) {			s = "0" + s;		}		return s;	}}


第四步:本项目需要处理界面的背景样式和按钮的背景,所以需要在res/drawable文件新建shape_main.xml。

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient        android:startColor="#FFCC99"        android:endColor="#99CC66"        android:centerColor="#0066CC"        android:angle="45" /></shape>

页面效果:

效果截图



下载地址:

该资源正在审核中,敬请期待!                         点此下载资源!

  相关解决方案