华域联盟 Andriod Android实现调用摄像头拍照与视频功能

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> 

页面效果:

效果截图

下载地址:Android实现调用摄像头拍照与视频功能

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

本文由 华域联盟 原创撰写:华域联盟 » Android实现调用摄像头拍照与视频功能

转载请保留出处和原文链接:https://www.cnhackhy.com/106476.htm

本文来自网络,不代表华域联盟立场,转载请注明出处。

作者: sterben

Android实现调用摄像头和相册的方法

发表回复

联系我们

联系我们

2551209778

在线咨询: QQ交谈

邮箱: [email protected]

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们