1. 程式人生 > >Android實現錄屏MediaProjection以及相關異常解決

Android實現錄屏MediaProjection以及相關異常解決

專案需要實現一個手機的錄屏功能,於是從網上找了些相關資料和原始碼,發現跑不起來,於是開始dubug,發現坑還是很多的,這裡記錄一下實現過程和一些些遇到的異常以及一個我調整完可以跑的Demo。

首先在AndroidManifest中靜態配置許可權:

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

然後在Activity中動態申請

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
    != PackageManager.PERMISSION_GRANTED) {
  ActivityCompat.requestPermissions(this,
      new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_REQUEST_CODE);
}

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO)
    != PackageManager.PERMISSION_GRANTED) {
  ActivityCompat.requestPermissions(this,
      new String[] {Manifest.permission.RECORD_AUDIO}, AUDIO_REQUEST_CODE);
}

因為專案中需要用到一個自定義的Application,所以要需要配置一個全域性的Application,同樣在AndroidManiest中在application新增自定義的類名,如果在裡面啟動服務了也要一併配置。

<application
    android:name=".RecordApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service android:name="com.example.administrator.screencap.RecordService"></service>
</application>

然後可以使用封裝好的實現其錄屏功能的service,這個封裝類是網上找的,看很多人在用,我解決了一些異常,並根據自己需求修改了一下。

其中主要異常有:

1.mediaRecorder報空指標,解決方案,在宣告的時候宣告為靜態

private static MediaRecorder mediaRecorder;

2.mediaRecorder.start()方法異常,在每次呼叫stop時要先呼叫

mediaRecorder.stop();
mediaRecorder.release();

兩個方法,並將

mediaRecorder = null。

3.

mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC)異常,這裡是設定音訊源,可嘗試將引數改為
MediaRecorder.AudioSource.DEFAULT

4.stop方法異常,如果是running狀態不正常,可能是其狀態丟失,需要將宣告的running也改為靜態的

0.增加需求,在生成視訊時大部分人都會根據mediaRecorder.setVideoSize(width, height);方法來定死視訊大小,導致一些手機會解析不了,或者是視訊比螢幕小,這裡提供一種根據螢幕大小動態設定視訊大小的方法。

這裡就要用到我們之前定義的全域性的Application,然後呼叫getInstance()獲取其例項,

然後通過

DisplayMetrics dm = RecordApplication.getInstance().getResources().getDisplayMetrics();
private int width = dm.widthPixels;
private int height = dm.heightPixels;
private int dpi = dm.densityDpi;

來獲取螢幕的長、寬和dpi的值,這裡不用WindowsManager方法是因為我是在非Activity去獲取螢幕長寬的,所以用了getDisplayMetrics();

這樣這個功能基本就是實現了。

Demo地址:https://github.com/han103070/Screencap