項目需要實現一個手機的錄屏功能,於是從網上找了些相關資料和源碼,發現跑不起來,於是開始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();
這樣這個功能基本就是實現了。