您好,登錄后才能下訂單哦!
應用場景:
在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實現調用攝像頭拍照與視頻功能
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。