Android 5.0+ 屏幕錄制實(shí)現(xiàn)的示例代碼
前言
Android 從 4.0 開(kāi)始就提供了手機(jī)錄屏方法,但是需要 root 權(quán)限,比較麻煩不容易實(shí)現(xiàn)。但是從 5.0 開(kāi)始,系統(tǒng)提供給了 app 錄制屏幕的一系列方法,不需要 root 權(quán)限,只需要用戶授權(quán)即可錄屏,相對(duì)來(lái)說(shuō)較為簡(jiǎn)單。本文是在參考了網(wǎng)絡(luò)上其他錄屏資料后完成的, 感謝 。以下將介紹開(kāi)發(fā)錄屏功能的一系列步驟以及實(shí)現(xiàn)過(guò)程中所遇到的一些需要注意的事項(xiàng)。
實(shí)現(xiàn)步驟
1、在清單文件中聲明需要的權(quán)限
因?yàn)殇浿朴玫禁溈孙L(fēng),所以需要加上 AUDIO 權(quán)限,
<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"/>
如果開(kāi)發(fā)的 app targetApi 在 6.0 以上時(shí),還需要?jiǎng)討B(tài)獲取權(quán)限。
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) {
//動(dòng)態(tài)申請(qǐng)
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、獲取用戶錄制屏幕授權(quán)
這里先介紹 MediaProjectionManager , MediaProjectionManager 是系統(tǒng)提供的一種服務(wù),當(dāng)我們拿到這個(gè)服務(wù)對(duì)象,可以創(chuàng)建一個(gè) Intent ,通過(guò)這個(gè) Intent 可以啟動(dòng)一個(gè)彈框樣式的 Activity,如果用戶授權(quán)了,那我們便可以繼續(xù)下一步屏幕錄制。需要說(shuō)明的是,Intent 是去啟動(dòng)另一個(gè) Activity 的,有極少極少的機(jī)型是沒(méi)有對(duì)應(yīng)的授權(quán)Activity 的,所以這里需要多加判斷,防止應(yīng)用奔潰。
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){
//存在錄屏授權(quán)的Activity
activity.startActivityForResult(intent,requestCode);
}else {
Toast.makeText(activity,R.string.can_not_record_tip,Toast.LENGTH_SHORT).show();
}
}
3、在 onActivityResult 對(duì)用戶的授權(quán)做處理
即使用戶授權(quán)了,同意錄制操作,仍然需要捕獲異常,因?yàn)橛锌赡軙?huì)出現(xiàn)這樣一種情況,就是用戶在同意錄屏的時(shí)候系統(tǒng)也正在錄屏,錄屏操作沖突了。
@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、創(chuàng)建 VirtualDisplay
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setUpMediaRecorder() {
mRecordFilePath = getSaveDirectory() + File.separator+ System.currentTimeMillis() + ".mp4";
if (mMediaRecorder == null){
mMediaRecorder = new MediaRecorder();
}
//設(shè)置音頻來(lái)源
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//設(shè)置視頻來(lái)源
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();
}
}
這一步是整個(gè)錄屏操作最為關(guān)鍵的一步!我們初始化了 MediaRecorder,設(shè)置了是否錄上聲音、錄屏文件格式、錄屏文件路徑、音視頻的編碼器、比特率、視頻幀率等
然后將在步驟 3 中的 resultCode 以及 data 作為必要的參數(shù)通過(guò) MediaProjectionManager 創(chuàng)建 VirtualDisplay。VirtualDisplay 可以理解為虛擬的呈現(xiàn)器,它可以捕獲屏幕上的內(nèi)容,并將其捕獲的內(nèi)容渲染到 Surface 上(Surace 由 MediaRecorder 提供,通過(guò) getSurface() 方法得到),MediaRecorder 再進(jìn)一步將其封裝處理為 Mp4 文件。
經(jīng)過(guò)以上步驟 prepare 之后,當(dāng)再次調(diào)用 MediaRecorder.start() 就可以開(kāi)始錄屏了,這里同意也需要注意的時(shí),調(diào)用 start() 方法開(kāi)始錄屏之后,不能立即調(diào)用 stop()方法停止錄屏,否則會(huì)奔潰。測(cè)試在測(cè)試錄屏功能時(shí)立馬停止錄屏,應(yīng)用奔潰,一直找不到原因。直到看到了源碼( API 26 )里的注釋

所以為了反正奔潰,在 stop 的時(shí)候捕獲異常,并且置空 MediaRecorder,下次錄屏的時(shí)候再重新生成 MediaRecorder。
最后
由于知識(shí)水平有限,難免有錯(cuò)誤遺漏,歡迎指正!項(xiàng)目地址為 屏幕錄制
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android異步方法以同步方式實(shí)現(xiàn)
- Android多線程之同步鎖的使用
- Android seekbar(自定義)控制音量同步更新
- android-獲取網(wǎng)絡(luò)時(shí)間、獲取特定時(shí)區(qū)時(shí)間、時(shí)間同步的方法
- android中ListView數(shù)據(jù)刷新時(shí)的同步方法
- Android實(shí)現(xiàn)歌曲播放時(shí)歌詞同步顯示具體思路
- Android獲取點(diǎn)擊屏幕的位置坐標(biāo)
- Android自適應(yīng)不同屏幕大小的全部方法
- Android6.0開(kāi)發(fā)中屏幕旋轉(zhuǎn)原理與流程分析
- Android手機(jī)屏幕同步工具asm.jar
相關(guān)文章
SpringBoot實(shí)現(xiàn)短信驗(yàn)證碼登錄功能(案例)
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)短信驗(yàn)證碼登錄功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-08-08
android事件分發(fā)機(jī)制的實(shí)現(xiàn)原理
本篇文章主要介紹了android事件分發(fā)機(jī)制的實(shí)現(xiàn)原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
Android JNI 調(diào)用時(shí)緩存字段和方法ID示例
這篇文章主要介紹了Android JNI 調(diào)用時(shí)緩存字段和方法ID示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
XListView實(shí)現(xiàn)下拉刷新和上拉加載原理解析
這篇文章主要為大家解析了XListView實(shí)現(xiàn)下拉刷新和上拉加載原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android利用zxing快速集成二維碼掃描的實(shí)例教程
最近二維碼真是越來(lái)越火了,隨便電視上、網(wǎng)絡(luò)上、商場(chǎng)里,到處都是二維碼,所以下面這篇文章我們就來(lái)給大家介紹關(guān)于Android利用zxing快速集成二維碼掃描的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起看看吧。2017-09-09
Android Zxing 轉(zhuǎn)換豎屏掃描且提高識(shí)別率的方法
本篇文章主要介紹了Android Zxing 轉(zhuǎn)換豎屏掃描且提高識(shí)別率的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Android 實(shí)現(xiàn)數(shù)字九宮格軟鍵盤(pán)
最近項(xiàng)目在對(duì)接美團(tuán)外賣功能,實(shí)現(xiàn)外面小哥憑取貨碼取貨,對(duì)接完功能后用戶反饋彈出的軟鍵盤(pán)很難輸入,數(shù)字太小了,于是便著手優(yōu)化一下2021-05-05

