中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

Android 5.0+ 屏幕錄制實現的示例代碼

發布時間:2020-08-31 21:56:41 來源:腳本之家 閱讀:326 作者:OhHoo 欄目:移動開發

前言

Android 從 4.0 開始就提供了手機錄屏方法,但是需要 root 權限,比較麻煩不容易實現。但是從 5.0 開始,系統提供給了 app 錄制屏幕的一系列方法,不需要 root 權限,只需要用戶授權即可錄屏,相對來說較為簡單。本文是在參考了網絡上其他錄屏資料后完成的, 感謝 。以下將介紹開發錄屏功能的一系列步驟以及實現過程中所遇到的一些需要注意的事項。

實現步驟

1、在清單文件中聲明需要的權限

因為錄制用到麥克風,所以需要加上 AUDIO 權限,

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

如果開發的 app targetApi 在 6.0 以上時,還需要動態獲取權限。

public static void checkPermission(AppCompatActivity activity) {
  if (Build.VERSION.SDK_INT >= 23) {
   int checkPermission =
     ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO)
       + ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE)
       + ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
       + ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
   if (checkPermission != PackageManager.PERMISSION_GRANTED) {
    //動態申請
    ActivityCompat.requestPermissions(activity, new String[]{
      Manifest.permission.RECORD_AUDIO,
      Manifest.permission.READ_PHONE_STATE,
      Manifest.permission.READ_EXTERNAL_STORAGE,
      Manifest.permission.WRITE_EXTERNAL_STORAGE}, 123);
    return;
   } else {
    return;
   }
  }
  return;
 }

2、獲取用戶錄制屏幕授權

這里先介紹 MediaProjectionManager , MediaProjectionManager 是系統提供的一種服務,當我們拿到這個服務對象,可以創建一個 Intent ,通過這個 Intent 可以啟動一個彈框樣式的 Activity,如果用戶授權了,那我們便可以繼續下一步屏幕錄制。需要說明的是,Intent 是去啟動另一個 Activity 的,有極少極少的機型是沒有對應的授權Activity 的,所以這里需要多加判斷,防止應用奔潰。

MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.
       getSystemService(Context.MEDIA_PROJECTION_SERVICE);
     if (mediaProjectionManager != null){
      Intent intent = mediaProjectionManager.createScreenCaptureIntent();
      PackageManager packageManager = activity.getPackageManager();
      if (packageManager.resolveActivity(intent,PackageManager.MATCH_DEFAULT_ONLY) != null){
       //存在錄屏授權的Activity 
       activity.startActivityForResult(intent,requestCode);
      }else {
       Toast.makeText(activity,R.string.can_not_record_tip,Toast.LENGTH_SHORT).show();
      }
     }

3、在 onActivityResult 對用戶的授權做處理

即使用戶授權了,同意錄制操作,仍然需要捕獲異常,因為有可能會出現這樣一種情況,就是用戶在同意錄屏的時候系統也正在錄屏,錄屏操作沖突了。

@Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK){
   try {
    ScreenUtil.setUpData(resultCode,data);
   } catch (Exception e) {
    e.printStackTrace();
   }
  } else {
   ToastUtil.show(this,"拒絕錄屏");
  }
 }

4、初始化 MediaRecorder、創建 VirtualDisplay

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 private void setUpMediaRecorder() {

  mRecordFilePath = getSaveDirectory() + File.separator+ System.currentTimeMillis() + ".mp4";
  if (mMediaRecorder == null){
   mMediaRecorder = new MediaRecorder();
  }
  //設置音頻來源
  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  //設置視頻來源
  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
  //輸出的錄屏文件格式
  mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
  //錄屏文件路徑
  mMediaRecorder.setOutputFile( mRecordFilePath );
  //視頻尺寸
  mMediaRecorder.setVideoSize(mRecordWidth, mRecordHeight);
  //音視頻編碼器
  mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
  mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  //比特率
  mMediaRecorder.setVideoEncodingBitRate((int) (mRecordWidth * mRecordHeight * 3.6));
  //視頻幀率
  mMediaRecorder.setVideoFrameRate(20);

  try {
   mMediaRecorder.prepare();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

這一步是整個錄屏操作最為關鍵的一步!我們初始化了 MediaRecorder,設置了是否錄上聲音、錄屏文件格式、錄屏文件路徑、音視頻的編碼器、比特率、視頻幀率等

然后將在步驟 3 中的 resultCode 以及 data 作為必要的參數通過 MediaProjectionManager 創建 VirtualDisplay。VirtualDisplay 可以理解為虛擬的呈現器,它可以捕獲屏幕上的內容,并將其捕獲的內容渲染到 Surface 上(Surace 由 MediaRecorder 提供,通過 getSurface() 方法得到),MediaRecorder 再進一步將其封裝處理為 Mp4 文件。

經過以上步驟 prepare 之后,當再次調用 MediaRecorder.start() 就可以開始錄屏了,這里同意也需要注意的時,調用 start() 方法開始錄屏之后,不能立即調用 stop()方法停止錄屏,否則會奔潰。測試在測試錄屏功能時立馬停止錄屏,應用奔潰,一直找不到原因。直到看到了源碼( API 26 )里的注釋

Android 5.0+ 屏幕錄制實現的示例代碼

所以為了反正奔潰,在 stop 的時候捕獲異常,并且置空 MediaRecorder,下次錄屏的時候再重新生成 MediaRecorder。

最后

由于知識水平有限,難免有錯誤遺漏,歡迎指正!項目地址為 屏幕錄制

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

柳江县| 东宁县| 区。| 洛南县| 四子王旗| 电白县| 韶山市| 茶陵县| 息烽县| 连平县| 科技| 东光县| 鄄城县| 田东县| 米脂县| 沁源县| 五台县| 浦城县| 金华市| 建昌县| 三都| 长宁县| 嘉善县| 通辽市| 攀枝花市| 舞阳县| 安新县| 茶陵县| 乌拉特前旗| 资中县| 花莲市| 张家港市| 九寨沟县| 象山县| 寻乌县| 加查县| 左权县| 松滋市| 富川| 明星| 河北区|