應用場景:
在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>
頁面效果:
效果截圖
	
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答