應用場景:
創(chuàng)新互聯(lián)建站是一家專業(yè)提供絳縣企業(yè)網(wǎng)站建設,專注與網(wǎng)站設計、網(wǎng)站建設、HTML5建站、小程序制作等業(yè)務。10年已為絳縣眾多企業(yè)、政府機構(gòu)等服務。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡公司優(yōu)惠進行中。
在Android開發(fā)過程中,有時需要調(diào)用手機自身設備的功能,上篇文章主要側(cè)重攝像頭拍照功能的調(diào)用。本篇文章將綜合實現(xiàn)拍照與視頻的操作。
知識點介紹:
該部分請閱讀 【Android 調(diào)用攝像頭功能】
使用方式:
第一步:
新建一個Android項目CameraPhotoVedio,包含兩個Activity: MainActivity、CameraActivity。
第二步:
activity_main.xml
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; //調(diào)用攝像頭按鈕 @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
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; //攝像區(qū)域是否準備良好 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);// 照片質(zhì)量 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; } }); //開發(fā)時建議設置 //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()); //開始捕捉和編碼數(shù)據(jù)到setOutputFile(指定的文件) mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); //設置用于錄制的音源 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //設置在錄制過程中產(chǎn)生的輸出文件的格式 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);// 照片質(zhì)量 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);// 照片質(zhì)量 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; } } } /* * 定時器設置,實現(xiàn)計時 */ 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 { /** * 將緩存文件夾的數(shù)據(jù)轉(zhuǎn)存到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); } /** * 用以計時操作的相關(guān)方法 * @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"?>
頁面效果:
效果截圖
下載地址:Android實現(xiàn)調(diào)用攝像頭拍照與視頻功能
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。