国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Android - Android使用MediaRecorder類實(shí)現(xiàn)視頻和音頻錄制功能

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

2022-03-09 15:27Chin_style Android

Android提供了MediaRecorder這一個(gè)類來(lái)實(shí)現(xiàn)視頻和音頻的錄制功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

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

一、前期基礎(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;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<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)備代碼;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
* 相機(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ǔ)位置代碼; 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
* 獲取手機(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ī)資源;

?
1
2
3
4
5
6
7
8
9
10
11
12
/*
* 錄制視頻結(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)擊停止錄制;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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)始播放錄制剛剛錄制好的視頻;      

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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();
 }
};

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
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)自服務(wù)器之家文章:Android動(dòng)態(tài)請(qǐng)求權(quán)限的工具類(可請(qǐng)求多個(gè),并且功能完善))

完整代碼如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
 * 運(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)限的代碼寫在工具類內(nèi) 同時(shí)寫入一個(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();
 }
}

總結(jié)

以上所述是小編給大家介紹的Android使用MediaRecorder實(shí)現(xiàn)錄制視頻功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!

原文鏈接:https://blog.csdn.net/weixin_41101173/article/details/80907365

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品一区在线观看 | 人人射| 国偷自产一区二区免费视频 | 成人免费观看www的片 | 综合av在线 | 青青草网站 | 久草视频国产 | 国产精品一区二区三区四区五区 | 亚洲国产精品一区二区三区 | 久久久91精品国产一区二区三区 | 亚洲精品一区二区三区蜜桃下载 | 午夜免费福利视频 | 国产日韩欧美在线观看 | 国产成人高清精品免费5388 | 日韩和的一区二在线 | 亚洲精品视频一区二区三区 | 夜夜春精品视频高清69式 | 亚洲视频第一页 | 亚洲福利社区 | 精品久久久久一区二区国产 | 精品一区二区三区久久 | 日本中文字幕在线观看 | 国产资源在线免费观看 | 91精品国产一区二区三区 | 国产精品毛片无码 | 午夜影院免费 | 午夜午夜精品一区二区三区文 | 99综合| 国产精品99久久久久久动医院 | 99在线观看 | 4438x成人网最大色成网站 | 久久久久久久久久久蜜桃 | 国产探花在线精品一区二区 | www.国产精品 | 日韩欧美一区二区在线视频 | 久久久一 | 美女网站黄视频 | 精品国内| 中文字幕av一区二区 | 欧美国产精品一区 | 激情欧美一区二区三区中文字幕 |