安卓双摄像头录像_Android实现调用摄像头拍照与视频功能

本文介绍了如何在Android应用中调用双摄像头进行录像和拍照。通过创建`CameraPhotoVedio`项目,包含`MainActivity`和`CameraActivity`两个Activity,详细讲解了布局设置、权限处理、相机初始化、拍照与录像功能的实现,以及计时功能的添加。文章还提到了工具类`FormatUtil`用于处理文件和时间格式,并提供了界面设计的资源文件。
摘要由CSDN通过智能技术生成

应用场景:

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

知识点介绍:

使用方式:

第一步:

新建一个Android项目CameraPhotoVedio,包含两个Activity: MainActivity、CameraActivity。

第二步:

activity_main.xml

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" >

android:layout_marginTop="50dp"

android:layout_width="match_parent"

android:orientation="vertical">

android:layout_width="wrap_content"

android:layout_gravity="center"

android:src="@drawable/main"/>

android:layout_marginTop="100dp"

android:layout_width="match_parent"

android:layout_alignParentBottom="true"

android:orientation="vertical">

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="使用摄像头"/>

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

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:background="#FFFFFF"

android:layout_height="match_parent"

tools:context=".CameraActivity" >

android:layout_width="match_parent"

android:layout_height="match_parent"

android:id="@+id/camera_surfaceview"/>

android:layout_width="wrap_content"

android:text="计时区域"

android:id="@+id/camera_time"/>

android:layout_width="match_parent"

android:layout_alignParentBottom="true"

android:orientation="horizontal">

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="照片摄取"/>

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="视频摄取"/>

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 {

@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。

android:startColor="#FFCC99"

android:endColor="#99CC66"

android:centerColor="#0066CC"

android:angle="45" />

页面效果:

效果截图

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值