溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android實(shí)現(xiàn)調(diào)用攝像頭拍照與視頻功能

發(fā)布時間:2020-09-25 10:11:07 來源:腳本之家 閱讀:140 作者:Hoking 欄目:移動開發(fā)

應(yīng)用場景:

在Android開發(fā)過程中,有時需要調(diào)用手機(jī)自身設(shè)備的功能,上篇文章主要側(cè)重?cái)z像頭拍照功能的調(diào)用。本篇文章將綜合實(shí)現(xiàn)拍照與視頻的操作。

知識點(diǎn)介紹:

該部分請閱讀 【Android 調(diào)用攝像頭功能】

使用方式:

第一步:

新建一個Android項(xiàng)目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; //調(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

<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="計(jì)時區(qū)域" 
  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; //攝像區(qū)域是否準(zhǔn)備良好 
 private boolean isRecording = true; // true表示沒有錄像,點(diǎn)擊開始;false表示正在錄像,點(diǎn)擊暫停 
 private boolean bool; 
  
 private int hour = 0; 
 private int minute = 0;  //計(jì)時專用 
 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(); 
    //設(shè)置Camera的角度/方向 
    camera.setDisplayOrientation(90); 
    Camera.Parameters parameters = camera.getParameters(); 
    parameters.setPreviewFrameRate(5); // 每秒5幀 
    parameters.setPictureFormat(ImageFormat.JPEG);// 設(shè)置照片的輸出格式 
    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ā)時建議設(shè)置 
  //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: 
    //點(diǎn)擊開始錄像 
    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(); 
     } 
     //表面設(shè)置顯示記錄媒體(視頻)的預(yù)覽 
     mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); 
     //開始捕捉和編碼數(shù)據(jù)到setOutputFile(指定的文件) 
     mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
     //設(shè)置用于錄制的音源 
     mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
     //設(shè)置在錄制過程中產(chǎn)生的輸出文件的格式 
     mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
     //設(shè)置視頻編碼器,用于錄制 
     mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); 
     //設(shè)置audio的編碼格式 
     mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
     //設(shè)置要捕獲的視頻的寬度和高度 
     mediaRecorder.setVideoSize(320, 240); 
     // 設(shè)置要捕獲的視頻幀速率 
     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 { 
     //點(diǎn)擊停止錄像 
     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);// 設(shè)置照片的輸出格式 
      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);// 設(shè)置照片的輸出格式 
      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; 
   } 
  } 
 } 
 /* 
  * 定時器設(shè)置,實(shí)現(xiàn)計(jì)時 
  */ 
 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; 
  } 
 } 
} 

第三步:該項(xiàng)目需要一個工具類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); 
 } 
  
 /** 
  * 用以計(jì)時操作的相關(guān)方法 
  * @param num 
  * @return 
  */ 
 public static String format(int num){ 
  String s = num + ""; 
  if (s.length() == 1) { 
   s = "0" + s; 
  } 
  return s; 
 } 
} 

第四步:本項(xiàng)目需要處理界面的背景樣式和按鈕的背景,所以需要在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實(shí)現(xiàn)調(diào)用攝像頭拍照與視頻功能

下載地址:Android實(shí)現(xiàn)調(diào)用攝像頭拍照與視頻功能

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI