怎么在Android中使用MediaRecorder類實(shí)現(xiàn)視頻和音頻錄制功能

怎么在Android中使用MediaRecorder類實(shí)現(xiàn)視頻和音頻錄制功能?相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

你所需要的網(wǎng)站建設(shè)服務(wù),我們均能行業(yè)靠前的水平為你提供.標(biāo)準(zhǔn)是產(chǎn)品質(zhì)量的保證,主要從事成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、企業(yè)網(wǎng)站建設(shè)、手機(jī)網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)、品牌網(wǎng)站制作、網(wǎng)頁(yè)制作、做網(wǎng)站、建網(wǎng)站。成都創(chuàng)新互聯(lián)公司擁有實(shí)力堅(jiān)強(qiáng)的技術(shù)研發(fā)團(tuán)隊(duì)及素養(yǎng)的視覺(jué)設(shè)計(jì)專才。

一、前期基礎(chǔ)知識(shí)儲(chǔ)備

Android提供了MediaRecorder這一個(gè)類來(lái)實(shí)現(xiàn)視頻和音頻的錄制。

怎么在Android中使用MediaRecorder類實(shí)現(xiàn)視頻和音頻錄制功能 

 由官方配圖可知,MediaRecorder用于錄制視頻時(shí)需要調(diào)用一系列的API來(lái)設(shè)置和錄制相關(guān)的配置,而且調(diào)用方法的順序是固定的,必須按照這個(gè)順序進(jìn)行API調(diào)用才能正確利用手機(jī)攝像頭實(shí)現(xiàn)錄像功能。

調(diào)用MediaRecorder的錄像API順序如下:

1)Open Camera - Use the Camera.open() to get an instance of the camera object.  

2)Connect Preview - Prepare a live camera image preview by connecting a SurfaceView to the camera using Camera.setPreviewDisplay(). 

 3)Start Preview - Call Camera.startPreview() to begin displaying the live camera images. 

 4)Start Recording Video - The following steps must be completed in order to successfully record video: 

a.Unlock the Camera - Unlock the camera for use by MediaRecorder by calling Camera.unlock(). 

 b.Configure MediaRecorder - Call in the following MediaRecorder methods in this order:

setCamera() - Set the camera to be used for video capture,綁定Camera進(jìn)行視頻錄制。
setAudioSource() - Set the audio source,設(shè)置音頻源。
setVideoSource() - Set the video source,設(shè)置視頻源。
setProfile() - Set the video output format and encoding,錄制效果的配置。
setOutputFile() - Set the output file, 設(shè)置錄制好的文件存儲(chǔ)位置。
setPreviewDisplay() - Connect Preview,設(shè)置預(yù)覽效果。

c.Prepare MediaRecorder- Prepare the MediaRecorder with provided configuration settings by calling MediaRecorder.prepare(). 

d.Start MediaRecorder - Start recording video by calling MediaRecorder.start().

停止錄像時(shí)調(diào)用的API順序如下:

1)Stop MediaRecorder - Stop recording video by calling MediaRecorder.stop().
 2)Reset MediaRecorder - Optionally, remove the configuration settings from the recorder by calling MediaRecorder.reset().
 3)Release MediaRecorder - Release the MediaRecorder by calling MediaRecorder.release().
 4)Lock the Camera - Lock the camera so that future MediaRecorder sessions can use it by calling Camera.lock().
 5)Stop the Preview - When your activity has finished using the camera, stop the preview using Camera.stopPreview().
 6)Release Camera - Release the camera so that other applications can use it by calling Camera.release().

二、上代碼,具體實(shí)現(xiàn)錄制視頻和視頻播放功能

這里調(diào)用MediaRecorder的API實(shí)現(xiàn)視頻錄制功能并借用MediaPlayer多媒體播放類實(shí)現(xiàn)錄制好的視頻播放。

(1)布局文件如下,非常簡(jiǎn)單兩個(gè)按鈕下放置一個(gè)SurfaceView;

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical">
  <LinearLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="horizontal">
   <Button
    android:id="@+id/record_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="15dp"
    android:layout_weight="1"
    android:text="record" />
   <Button
    android:id="@+id/play_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="15dp"
    android:layout_weight="1"
    android:text="play" />
  </LinearLayout>
  <SurfaceView
   android:id="@+id/surface_view"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginBottom="20dp" />
 </LinearLayout>

(2)相機(jī)錄像前的準(zhǔn)備代碼;

 /*
 * 相機(jī)預(yù)覽前的準(zhǔn)備工作代碼 單獨(dú)抽出來(lái)
 * */
 private boolean prepareVideoRecorder() throws IOException {
  if (mMediaRecorder == null) {
   mMediaRecorder = new MediaRecorder();
   mMediaRecorder.reset();
  }
   /*camera相關(guān)設(shè)置部分*/
  mCamera = Camera.open(0);//Camera.CameraInfo.CAMERA_FACING_BACK
  if (mCamera != null) {
   //設(shè)置旋轉(zhuǎn)角度,順時(shí)針?lè)较?,因?yàn)槟J(rèn)是逆向90度的,這樣圖像就是正常顯示了
   mCamera.setDisplayOrientation(90);
   mCamera.unlock();
   mMediaRecorder.setCamera(mCamera);
  }
   /*recorder設(shè)置部分*/
  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
  mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
  mMediaRecorder.setOutputFile(getOutputMediaFile());
  mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
  mMediaRecorder.prepare();
  return true;
 }

(3)創(chuàng)建錄像文件存儲(chǔ)位置代碼; 

 /*
 * 獲取手機(jī)外部存儲(chǔ)路徑
 * */
 private String getOutputFile() {
  File mediaFile = null;
  boolean OutputExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
  if (OutputExist) {
   mediaFile = Environment.getExternalStorageDirectory();
   return mediaFile.toString();
  }
  return null;
 }
 /*
 * 獲取錄制視頻的日期 作為存儲(chǔ)文件路徑一部分
 * */
 private String getDate() {
  Log.d(TAG, "獲取錄制視頻的日期 ");
  Calendar ca = Calendar.getInstance();
  int year = ca.get(Calendar.YEAR);   // 獲取年份
  int month = ca.get(Calendar.MONTH);   // 獲取月份
  int day = ca.get(Calendar.DATE);   // 獲取日
  String date = "" + year + "_" + (month + 1) + "_" + day;
  return date;
 }
 /*
 *創(chuàng)建視頻存儲(chǔ)文件夾 錄制好的視頻存儲(chǔ)在手機(jī)外部存儲(chǔ)中 以錄像時(shí)間+mp4格式命名
 * */
 private String getOutputMediaFile() {
  Log.d(TAG, "獲取視頻存儲(chǔ)的位置 ");
  String mediaPath = getOutputFile();
  if (mediaPath != null) {
   File mediaFile = new File(mediaPath + "/recordVideo");
   if (!mediaFile.exists()) {
    mediaFile.mkdir();
   }
   return mMediaPath = mediaFile.getAbsolutePath() + File.separator + getDate() + ".mp4";
  }
  return null;
 }

(4)錄制視頻結(jié)束時(shí)釋放相機(jī)資源;

 /*
 * 錄制視頻結(jié)束時(shí)釋放相機(jī)資源
 * */
 private void releaseMediaRecorder() {
  Log.d(TAG, "錄制結(jié)束后釋放資源 ");
  if (mMediaRecorder != null) {
   mMediaRecorder.reset(); // clear recorder configuration
   mMediaRecorder.release(); // release the recorder object
   mMediaRecorder = null;
   mCamera.lock();   // lock camera for later use
  }
 }

(5)點(diǎn)擊錄制視頻按鈕mRecordBtn開(kāi)始錄制和再次點(diǎn)擊停止錄制;

 private void initBtnClick() {
  StartRecording();
  mPlayBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    if (mMediaPlayer == null) {
     mMediaPlayer = new MediaPlayer();
     mMediaPlayer.reset();
     Uri uri = Uri.parse(mMediaPath);
     mMediaPlayer = MediaPlayer.create(MainActivity.this,uri);
     mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
     mMediaPlayer.setDisplay(mSurfaceHolder);
     try{
      mMediaPlayer.prepare();
     }catch (Exception e){
      e.printStackTrace();
     }
     mMediaPlayer.start();
    }
   }
  });
 }
 private void StartRecording(){
  mRecordBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    if (!mIsRecord) {
     try {
      Log.d(TAG, "首次點(diǎn)擊開(kāi)始錄像 ");
      if (prepareVideoRecorder()) {
       mMediaRecorder.start();
       mIsRecord = true;
       mRecordBtn.setText("stop");
      }
     } catch (IOException e) {
      e.printStackTrace();
     }
    } else {
     Log.d(TAG, "再次點(diǎn)擊停止錄像");
     mMediaRecorder.stop();
     releaseMediaRecorder();
     mCamera.lock();
     mRecordBtn.setText("record");
     mIsRecord = false;
     if (mCamera != null) {
      mCamera.release();
      mCamera = null;
     }
    }
   }
  });
 }

(6)點(diǎn)擊播放視頻按鈕 mPlayBtn開(kāi)始播放錄制剛剛錄制好的視頻;      

 mPlayBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    if (mMediaPlayer == null) {
     mMediaPlayer = new MediaPlayer();
     mMediaPlayer.reset();
     Uri uri = Uri.parse(mMediaPath);
     mMediaPlayer = MediaPlayer.create(MainActivity.this,uri);
     mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
     mMediaPlayer.setDisplay(mSurfaceHolder);
     try{
      mMediaPlayer.prepare();
     }catch (Exception e){
      e.printStackTrace();
     }
     mMediaPlayer.start();
    }
   }
  });

(7)針對(duì)6.0以上系統(tǒng)進(jìn)行運(yùn)行時(shí)權(quán)限申請(qǐng)

 private void requestCameraAndStoragePermission() {
  //檢查用戶是否授權(quán)
  for (int i = 0; i < permissions.length; i++) {
   if (ContextCompat.checkSelfPermission(MainActivity.this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
    //沒(méi)有授權(quán)則請(qǐng)求相應(yīng)權(quán)限
    ActivityCompat.requestPermissions(MainActivity.this, new String[]{permissions[i]}, 1);
   }
  }
  //利用權(quán)限申請(qǐng)工具類來(lái)實(shí)現(xiàn)
  mPermissionsUtils = PermissionsUtils.getInstance();
  mPermissionsUtils.chekPermissions(MainActivity.this,permissions, permissionsResult);
 }
 //創(chuàng)建監(jiān)聽(tīng)權(quán)限的接口對(duì)象
 PermissionsUtils.IPermissionsResult permissionsResult = new PermissionsUtils.IPermissionsResult() {
  @Override
  public void passPermissons() {
  //StartRecording(); 注意這里的邏輯 并不是權(quán)限通過(guò)了就立即開(kāi)始錄像了 而是權(quán)限通過(guò)了 就可以打開(kāi)Camera進(jìn)行預(yù)覽
   mCamera = Camera.open(0);//Camera.CameraInfo.CAMERA_FACING_BACK
  }
  @Override
  public void forbitPermissons() {
   Toast.makeText(MainActivity.this, "You denyied the permission", Toast.LENGTH_SHORT).show();
  }
 };

錄制視頻及播放錄制視頻完整代碼如下

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{
 private static final String TAG = "MainActivity";
 private SurfaceView mSurfaceView;
 private Button mRecordBtn, mPlayBtn;
 private boolean mIsRecord = false; //是否正在錄像
 private Camera mCamera;
 private MediaRecorder mMediaRecorder;
 private String mMediaPath;
 private MediaPlayer mMediaPlayer;
 private SurfaceHolder mSurfaceHolder;
 private PermissionsUtils mPermissionsUtils;
 private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE,
         Manifest.permission.CAMERA,
         Manifest.permission.RECORD_AUDIO};
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //6.0及以上系統(tǒng)請(qǐng)求運(yùn)行時(shí)權(quán)限 利用權(quán)限申請(qǐng)工具類(見(jiàn)下文)
  requestCameraAndStoragePermission();
  mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
  mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 必須-設(shè)置Surface不需要維護(hù)自己的緩沖區(qū)
  mRecordBtn = (Button) findViewById(R.id.record_btn);
  mPlayBtn = (Button) findViewById(R.id.play_btn);
  initBtnClick();
  SurfaceHolder holder = mSurfaceView.getHolder();
  holder.addCallback(this);
 }
 private void requestCameraAndStoragePermission() {
  //檢查用戶是否授權(quán)
  for (int i = 0; i < permissions.length; i++) {
   if (ContextCompat.checkSelfPermission(MainActivity.this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
    //沒(méi)有授權(quán)則請(qǐng)求相應(yīng)權(quán)限
    ActivityCompat.requestPermissions(MainActivity.this, new String[]{permissions[i]}, 1);
   }
  }
  //利用權(quán)限申請(qǐng)工具類來(lái)實(shí)現(xiàn)
  mPermissionsUtils = PermissionsUtils.getInstance();
  mPermissionsUtils.chekPermissions(MainActivity.this,permissions, permissionsResult);
 }
 //創(chuàng)建監(jiān)聽(tīng)權(quán)限的接口對(duì)象
 PermissionsUtils.IPermissionsResult permissionsResult = new PermissionsUtils.IPermissionsResult() {
  @Override
  public void passPermissons() {
//   StartRecording(); 注意這里的邏輯 并不是權(quán)限通過(guò)了就立即開(kāi)始錄像了 而是權(quán)限通過(guò)了 就可以打開(kāi)Camera進(jìn)行預(yù)覽
   mCamera = Camera.open(0);//Camera.CameraInfo.CAMERA_FACING_BACK
  }
  @Override
  public void forbitPermissons() {
   Toast.makeText(MainActivity.this, "You denyied the permission", Toast.LENGTH_SHORT).show();
  }
 };
 private void StartRecording(){
  mRecordBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    if (!mIsRecord) {
     try {
      Log.d(TAG, "首次點(diǎn)擊開(kāi)始錄像 ");
      if (prepareVideoRecorder()) {
       mMediaRecorder.start();
       mIsRecord = true;
       mRecordBtn.setText("stop");
      }
     } catch (IOException e) {
      e.printStackTrace();
     }
    } else {
     Log.d(TAG, "再次點(diǎn)擊停止錄像");
     mMediaRecorder.stop();
     releaseMediaRecorder();
     mCamera.lock();
     mRecordBtn.setText("record");
     mIsRecord = false;
     if (mCamera != null) {
      mCamera.release();
      mCamera = null;
     }
    }
   }
  });
 }
 private void initBtnClick() {
  StartRecording();
  mPlayBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    if (mMediaPlayer == null) {
     mMediaPlayer = new MediaPlayer();
     mMediaPlayer.reset();
     Uri uri = Uri.parse(mMediaPath);
     mMediaPlayer = MediaPlayer.create(MainActivity.this,uri);
     mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
     mMediaPlayer.setDisplay(mSurfaceHolder);
     try{
      mMediaPlayer.prepare();
     }catch (Exception e){
      e.printStackTrace();
     }
     mMediaPlayer.start();
    }
   }
  });
 }
 /*
 * 相機(jī)預(yù)覽前的準(zhǔn)備工作代碼 單獨(dú)抽出來(lái)
 * */
 private boolean prepareVideoRecorder() throws IOException {
  if (mMediaRecorder == null) {
   mMediaRecorder = new MediaRecorder();
   mMediaRecorder.reset();
  }
   /*camera相關(guān)設(shè)置部分*/
  mCamera = Camera.open(0);//Camera.CameraInfo.CAMERA_FACING_BACK
  if (mCamera != null) {
   //設(shè)置旋轉(zhuǎn)角度,順時(shí)針?lè)较?,因?yàn)槟J(rèn)是逆向90度的,這樣圖像就是正常顯示了
   mCamera.setDisplayOrientation(90);
   mCamera.unlock();
   mMediaRecorder.setCamera(mCamera);
  }
   /*recorder設(shè)置部分*/
  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
  mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
  mMediaRecorder.setOutputFile(getOutputMediaFile());
  mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
  mMediaRecorder.prepare();
  return true;
 }
 /*
 * 獲取手機(jī)外部存儲(chǔ)路徑
 * */
 private String getOutputFile() {
  File mediaFile = null;
  boolean OutputExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
  if (OutputExist) {
   mediaFile = Environment.getExternalStorageDirectory();
   return mediaFile.toString();
  }
  return null;
 }
 /*
 * 獲取錄制視頻的日期 作為存儲(chǔ)文件路徑一部分
 * */
 private String getDate() {
  Log.d(TAG, "獲取錄制視頻的日期 ");
  Calendar ca = Calendar.getInstance();
  int year = ca.get(Calendar.YEAR);   // 獲取年份
  int month = ca.get(Calendar.MONTH);   // 獲取月份
  int day = ca.get(Calendar.DATE);   // 獲取日
  String date = "" + year + "_" + (month + 1) + "_" + day;
  return date;
 }
 /*
 *創(chuàng)建視頻存儲(chǔ)文件夾 錄制好的視頻存儲(chǔ)在手機(jī)外部存儲(chǔ)中 以錄像時(shí)間+mp4格式命名
 * */
 private String getOutputMediaFile() {
  Log.d(TAG, "獲取視頻存儲(chǔ)的位置 ");
  String mediaPath = getOutputFile();
  if (mediaPath != null) {
   File mediaFile = new File(mediaPath + "/recordVideo");
   if (!mediaFile.exists()) {
    mediaFile.mkdir();
   }
   return mMediaPath = mediaFile.getAbsolutePath() + File.separator + getDate() + ".mp4";
  }
  return null;
 }
 /*
 * 錄制視頻結(jié)束時(shí)釋放相機(jī)資源
 * */
 private void releaseMediaRecorder() {
  Log.d(TAG, "錄制結(jié)束后釋放資源 ");
  if (mMediaRecorder != null) {
   mMediaRecorder.reset(); // clear recorder configuration
   mMediaRecorder.release(); // release the recorder object
   mMediaRecorder = null;
   mCamera.lock();   // lock camera for later use
  }
 }
 @Override
 public void surfaceCreated(SurfaceHolder surfaceHolder) {
  mSurfaceHolder = surfaceHolder;
 }
 @Override
 public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
  mSurfaceHolder = surfaceHolder;
 }
 @Override
 public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
  mSurfaceView = null;
  mSurfaceHolder = null;
  releaseMediaRecorder();
  if (mCamera != null) {
   mCamera.release();
   mCamera = null;
  }
  if (mMediaPlayer != null){
   mMediaPlayer.release();
   mMediaPlayer = null;
  }
 }
}

三、延伸知識(shí),運(yùn)行時(shí)權(quán)限申請(qǐng)工具類

調(diào)用手機(jī)系統(tǒng)內(nèi)置的攝像頭進(jìn)行視頻錄制時(shí)及錄制視頻后將視頻保存在本地都需要申請(qǐng)系統(tǒng)權(quán)限,而且申請(qǐng)的權(quán)限(調(diào)用攝像頭權(quán)限、存儲(chǔ)權(quán)限)都屬于26個(gè)危險(xiǎn)權(quán)限,針對(duì)6.0以上的手機(jī),需要進(jìn)行運(yùn)行時(shí)權(quán)限的申請(qǐng),由于申請(qǐng)的權(quán)限過(guò)多,而且申請(qǐng)的時(shí)間不一致,所以這里提供一個(gè)權(quán)限申請(qǐng)工具類協(xié)助實(shí)現(xiàn)權(quán)限申請(qǐng)。(來(lái)自創(chuàng)新互聯(lián)文章:Android動(dòng)態(tài)請(qǐng)求權(quán)限的工具類(可請(qǐng)求多個(gè),并且功能完善))

完整代碼如下

/**
 * 運(yùn)行時(shí)權(quán)限申請(qǐng)工具類:
 * 檢查用戶是否授權(quán)——ContextCompat.checkSelfPermission
 * 如果沒(méi)有授權(quán),那么申請(qǐng)授權(quán)——ActivityCompat.requestPermissions
 * 申請(qǐng)授權(quán)之后的回調(diào)——onRequestPermissionsResult
 * 精髓:檢查權(quán)限 申請(qǐng)權(quán)限的代碼寫(xiě)在工具類內(nèi) 同時(shí)寫(xiě)入一個(gè)接口 兩個(gè)抽象方法-獲取權(quán)限成功 + 獲取權(quán)限失敗 然后在外部使用權(quán)限工具類時(shí)實(shí)現(xiàn)這兩個(gè)抽象方法
 * Created by Administrator on 2018/7/3.
 */
public class PermissionsUtils {
 private final int mRequestCode = 100;//權(quán)限請(qǐng)求碼
 public static boolean showSystemSetting = true;
 private PermissionsUtils() {
 }
 private static PermissionsUtils permissionsUtils;
 private IPermissionsResult mPermissionsResult;
 /*
 * 單例模式創(chuàng)建PermissionUtils實(shí)例 工具類中的靜態(tài)方法可以直接使用類名+方法名調(diào)用 非靜態(tài)方法還是需要獲取到工具類的實(shí)例 實(shí)例對(duì)方法進(jìn)行調(diào)用
 * */
 public static PermissionsUtils getInstance() {
  if (permissionsUtils == null) {
   synchronized (PermissionsUtils.class) {
    if (permissionsUtils == null)
    permissionsUtils = new PermissionsUtils();
   }
  }
  return permissionsUtils;
 }
 /*
 * 檢查用戶是否授權(quán) + 如果沒(méi)有授權(quán) 則申請(qǐng)授權(quán) - 系統(tǒng)標(biāo)準(zhǔn)方法
 * */
 public void chekPermissions(Activity context, String[] permissions, @NonNull IPermissionsResult permissionsResult) {
  mPermissionsResult = permissionsResult;
  if (Build.VERSION.SDK_INT < 23) {//6.0系統(tǒng)及以上才會(huì)動(dòng)態(tài)申請(qǐng)權(quán)限 以下不用 所以直接return出去
   permissionsResult.passPermissons();
   return;
  }
  //創(chuàng)建一個(gè)mPermissionList,逐個(gè)判斷哪些權(quán)限未授予,未授予的權(quán)限存儲(chǔ)到mPerrrmissionList中
  List<String> mPermissionList = new ArrayList<>();
  //逐個(gè)判斷你要的權(quán)限是否已經(jīng)通過(guò)
  for (int i = 0; i < permissions.length; i++) {
   if (ContextCompat.checkSelfPermission(context, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
    mPermissionList.add(permissions[i]);//添加還未授予的權(quán)限
   }
  }
  //申請(qǐng)權(quán)限
  if (mPermissionList.size() > 0) {//有權(quán)限沒(méi)有通過(guò),需要申請(qǐng)
   ActivityCompat.requestPermissions(context, permissions, mRequestCode);
  } else {
   //說(shuō)明權(quán)限都已經(jīng)通過(guò),利用接口變量調(diào)用實(shí)現(xiàn)的接口方法 即有權(quán)限之后需要調(diào)用的方法
   permissionsResult.passPermissons();
   return;
  }
 }
 //請(qǐng)求權(quán)限后回調(diào)的方法
 //參數(shù): requestCode 是我們自己定義的權(quán)限請(qǐng)求碼
 //參數(shù): permissions 是我們請(qǐng)求的權(quán)限名稱數(shù)組
 //參數(shù): grantResults 是我們?cè)趶棾鲰?yè)面后是否允許權(quán)限的標(biāo)識(shí)數(shù)組,數(shù)組的長(zhǎng)度對(duì)應(yīng)的是權(quán)限名稱數(shù)組的長(zhǎng)度,數(shù)組的數(shù)據(jù)0表示允許權(quán)限,-1表示我們點(diǎn)擊了禁止權(quán)限
 public void onRequestPermissionsResult(Activity context, int requestCode, @NonNull String[] permissions,
           @NonNull int[] grantResults) {
  boolean hasPermissionDismiss = false;//有權(quán)限沒(méi)有通過(guò)
  if (mRequestCode == requestCode) {
   for (int i = 0; i < grantResults.length; i++) {
    if (grantResults[i] == -1) {
     hasPermissionDismiss = true;
    }
   }
   //如果有權(quán)限沒(méi)有被允許
   if (hasPermissionDismiss) {
    if (showSystemSetting) {
     showSystemPermissionsSettingDialog(context);//跳轉(zhuǎn)到系統(tǒng)設(shè)置權(quán)限頁(yè)面,或者直接關(guān)閉頁(yè)面,不讓他繼續(xù)訪問(wèn)
    } else {
     mPermissionsResult.forbitPermissons();
    }
   } else {
    //全部權(quán)限通過(guò),可以進(jìn)行下一步操作。。。
    mPermissionsResult.passPermissons();
   }
  }
 }
 /**
  * 不再提示權(quán)限時(shí)的展示對(duì)話框
  */
 AlertDialog mPermissionDialog;
 private void showSystemPermissionsSettingDialog(final Activity context) {
  final String mPackName = context.getPackageName();
  if (mPermissionDialog == null) {
   mPermissionDialog = new AlertDialog.Builder(context)
     .setMessage("已禁用權(quán)限,請(qǐng)手動(dòng)授予")
     .setPositiveButton("設(shè)置", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
       cancelPermissionDialog();
       Uri packageURI = Uri.parse("package:" + mPackName);
       Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
       context.startActivity(intent);
       context.finish();
      }
     })
     .setNegativeButton("取消", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
       //關(guān)閉頁(yè)面或者做其他操作
       cancelPermissionDialog();
       //mContext.finish();
       mPermissionsResult.forbitPermissons();
      }
     })
     .create();
  }
  mPermissionDialog.show();
 }
 //關(guān)閉對(duì)話框
 private void cancelPermissionDialog() {
  if (mPermissionDialog != null) {
   mPermissionDialog.cancel();
   mPermissionDialog = null;
  }
 }
 public interface IPermissionsResult {
  void passPermissons();
  void forbitPermissons();
 }
}

看完上述內(nèi)容,你們掌握怎么在Android中使用MediaRecorder類實(shí)現(xiàn)視頻和音頻錄制功能的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

當(dāng)前文章:怎么在Android中使用MediaRecorder類實(shí)現(xiàn)視頻和音頻錄制功能
路徑分享:http://muchs.cn/article0/ghipoo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、靜態(tài)網(wǎng)站網(wǎng)站導(dǎo)航、做網(wǎng)站、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)