android實(shí)現(xiàn)錄屏功能
本文實(shí)例為大家分享了android實(shí)現(xiàn)錄屏功能的具體代碼,供大家參考,具體內(nèi)容如下
1、mian.activity
package com.fpt.screenvideo; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.media.projection.MediaProjectionManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.RadioGroup; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private Button mTextView,off_btn; private static final String RECORD_STATUS = "record_status"; private static final int REQUEST_CODE = 1000; private int mScreenWidth; private int mScreenHeight; private int mScreenDensity; /** 是否已經(jīng)開啟視頻錄制 */ private boolean isStarted = false; /** 是否為標(biāo)清視頻 */ private boolean isVideoSd = true; /** 是否開啟音頻錄制 */ private boolean isAudio = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, "onCreate"); if(savedInstanceState != null) { isStarted = savedInstanceState.getBoolean(RECORD_STATUS); } getView() ; getScreenBaseInfo(); } private void getView() { mTextView = findViewById(R.id.button_control); off_btn=findViewById(R.id.button_contro2); off_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //// Intent service = new Intent(this, ScreenRecordService.class); // stopService(service); // isStarted = !isStarted; } }); if(isStarted) { statusIsStarted(); } else { statusIsStoped(); } mTextView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if(isStarted) { stopScreenRecording();//功能 statusIsStoped();//僅僅是狀態(tài) Log.i(TAG, "Stoped screen recording"); } else { startScreenRecording();//功能 } } }); RadioGroup radioGroup = (RadioGroup) findViewById(R.id.redio_group); radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { // TODO Auto-generated method stub switch (checkedId) { case R.id.sd_button: isVideoSd = true; break; case R.id.hd_button: isVideoSd = false; break; default: break; } } }); CheckBox audioBox = (CheckBox) findViewById(R.id.audio_check_box); audioBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // TODO Auto-generated method stub isAudio = isChecked; } }); } /** * 開啟屏幕錄制時(shí)的UI狀態(tài) */ private void statusIsStarted() { mTextView.setText("停止錄制"); mTextView.setBackgroundColor(Color.GREEN); } /** * 結(jié)束屏幕錄制后的UI狀態(tài) */ private void statusIsStoped() { mTextView.setText("開始錄制"); mTextView.setBackgroundColor(Color.RED); } /** * 獲取屏幕相關(guān)數(shù)據(jù) */ private void getScreenBaseInfo() { DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); mScreenWidth = metrics.widthPixels; mScreenHeight = metrics.heightPixels; mScreenDensity = metrics.densityDpi; } @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); outState.putBoolean(RECORD_STATUS, isStarted); } /** * 獲取屏幕錄制的權(quán)限 */ private void startScreenRecording() { // TODO Auto-generated method stub MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE); Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent(); startActivityForResult(permissionIntent, REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if(requestCode == REQUEST_CODE) { if(resultCode == RESULT_OK) { // 獲得權(quán)限,啟動(dòng)Service開始錄制 Intent service = new Intent(this, ScreenRecordService.class); service.putExtra("code", resultCode); service.putExtra("data", data); service.putExtra("audio", isAudio); service.putExtra("width", mScreenWidth); service.putExtra("height", mScreenHeight); service.putExtra("density", mScreenDensity); service.putExtra("quality", isVideoSd); startService(service); // 已經(jīng)開始屏幕錄制,修改UI狀態(tài) isStarted = !isStarted; statusIsStarted(); // simulateHome(); // this.finish(); // 可以直接關(guān)閉Activity Log.i(TAG, "Started screen recording"); } else { Toast.makeText(this, "跳出提示框", Toast.LENGTH_LONG).show(); Log.i(TAG, "User cancelled"); } } } /** * 關(guān)閉屏幕錄制,即停止錄制Service */ private void stopScreenRecording() { // TODO Auto-generated method stub Intent service = new Intent(this, ScreenRecordService.class); stopService(service); isStarted = !isStarted; } /** * 模擬HOME鍵返回桌面的功能 */ private void simulateHome() { Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addCategory(Intent.CATEGORY_HOME); this.startActivity(intent); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // 在這里將BACK鍵模擬了HOME鍵的返回桌面功能(并無(wú)必要) if(keyCode == KeyEvent.KEYCODE_BACK) { simulateHome(); return true; } return super.onKeyDown(keyCode, event); } }
2、ScreenRecordService
package com.fpt.screenvideo; import android.app.Service; import android.content.Context; import android.content.Intent; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.MediaRecorder; import android.media.projection.MediaProjection; import android.media.projection.MediaProjectionManager; import android.os.Environment; import android.os.IBinder; import android.util.Log; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class ScreenRecordService extends Service { private static final String TAG = "ScreenRecordingService"; private int mScreenWidth; private int mScreenHeight; private int mScreenDensity; private int mResultCode; private Intent mResultData; /** 是否為標(biāo)清視頻 */ private boolean isVideoSd; /** 是否開啟音頻錄制 */ private boolean isAudio; private MediaProjection mMediaProjection; private MediaRecorder mMediaRecorder; private VirtualDisplay mVirtualDisplay; @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Log.i(TAG, "Service onCreate() is called"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.i(TAG, "Service onStartCommand() is called"); mResultCode = intent.getIntExtra("code", -1); mResultData = intent.getParcelableExtra("data"); mScreenWidth = intent.getIntExtra("width", 720); mScreenHeight = intent.getIntExtra("height", 1280); mScreenDensity = intent.getIntExtra("density", 1); isVideoSd = intent.getBooleanExtra("quality", true); isAudio = intent.getBooleanExtra("audio", true); mMediaProjection = createMediaProjection(); mMediaRecorder = createMediaRecorder(); mVirtualDisplay = createVirtualDisplay(); // 必須在mediaRecorder.prepare() 之后調(diào)用,否則報(bào)錯(cuò)"fail to get surface" mMediaRecorder.start(); return Service.START_NOT_STICKY; } private MediaProjection createMediaProjection() { Log.i(TAG, "Create MediaProjection"); return ((MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE)).getMediaProjection(mResultCode, mResultData); } private MediaRecorder createMediaRecorder() { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); Date curDate = new Date(System.currentTimeMillis()); String curTime = formatter.format(curDate).replace(" ", ""); String videoQuality = "HD"; if(isVideoSd) videoQuality = "SD"; Log.i(TAG, "Create MediaRecorder"); MediaRecorder mediaRecorder = new MediaRecorder(); // if(isAudio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/" + videoQuality + curTime + ".mp4"); mediaRecorder.setVideoSize(mScreenWidth, mScreenHeight); //after setVideoSource(), setOutFormat() mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); //after setOutputFormat() // if(isAudio) mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //after setOutputFormat() int bitRate; if(isVideoSd) { mediaRecorder.setVideoEncodingBitRate(mScreenWidth * mScreenHeight); mediaRecorder.setVideoFrameRate(30); bitRate = mScreenWidth * mScreenHeight / 1000; } else { mediaRecorder.setVideoEncodingBitRate(5 * mScreenWidth * mScreenHeight); mediaRecorder.setVideoFrameRate(60); //after setVideoSource(), setOutFormat() bitRate = 5 * mScreenWidth * mScreenHeight / 1000; } try { mediaRecorder.prepare(); } catch (IllegalStateException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } Log.i(TAG, "Audio: " + isAudio + ", SD video: " + isVideoSd + ", BitRate: " + bitRate + "kbps"); return mediaRecorder; } private VirtualDisplay createVirtualDisplay() { Log.i(TAG, "Create VirtualDisplay"); return mMediaProjection.createVirtualDisplay(TAG, mScreenWidth, mScreenHeight, mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null); } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Log.i(TAG, "Service onDestroy"); if(mVirtualDisplay != null) { mVirtualDisplay.release(); mVirtualDisplay = null; } if(mMediaRecorder != null) { mMediaRecorder.setOnErrorListener(null); mMediaProjection.stop(); mMediaRecorder.reset(); } if(mMediaProjection != null) { mMediaProjection.stop(); mMediaProjection = null; } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }
3、androidManifest.xml權(quán)限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
4、service的注冊(cè)
<service android:name=".ScreenRecordService"/>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android MediaRecorder實(shí)現(xiàn)錄屏?xí)r帶錄音功能
- Android錄屏的三種解決方案
- 淺析Android錄屏 MediaRecorder
- android實(shí)現(xiàn)錄屏小功能
- android設(shè)置adb自帶screenrecord錄屏命令
- android桌面懸浮窗顯示錄屏?xí)r間控制效果
- Android錄屏功能的實(shí)現(xiàn)
- Android5.0以上版本錄屏實(shí)現(xiàn)代碼(完整代碼)
- android視頻截屏&手機(jī)錄屏實(shí)現(xiàn)代碼
- Android開發(fā)實(shí)現(xiàn)錄屏小功能
相關(guān)文章
Android App支付系列(二):支付寶SDK接入詳細(xì)指南(附官方支付demo)
本篇文章介紹了Android App支付系列(二):支付寶SDK接入詳細(xì)指南(附官方支付demo) ,有興趣的同學(xué)可以了解一下。2016-11-11Android Fragment滑動(dòng)組件ViewPager的實(shí)例詳解
這篇文章主要介紹了Android Fragment滑動(dòng)組件ViewPager的實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05android 獲取本機(jī)的IP地址和mac物理地址的實(shí)現(xiàn)方法
本文主要介紹android 獲取本機(jī)的IP地址和mac物理地址的實(shí)現(xiàn)方法,這里提供示例代碼,實(shí)現(xiàn)功能,有需要的小伙伴可以參考下2016-09-09android7.0實(shí)現(xiàn)分享圖片到朋友圈功能
這篇文章主要為大家詳細(xì)介紹了android7.0實(shí)現(xiàn)分享圖片到朋友圈功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android性能調(diào)優(yōu)利器StrictMode應(yīng)用分析
StrictMode意思為嚴(yán)格模式,是用來(lái)檢測(cè)程序中違例情況的開發(fā)者工具。最常用的場(chǎng)景就是檢測(cè)主線程中本地磁盤和網(wǎng)絡(luò)讀寫等耗時(shí)的操作。這篇文章給大家介紹Android性能調(diào)優(yōu)利器StrictMode應(yīng)用分析,感興趣的朋友一起看看吧2018-01-01android開發(fā)教程之textview內(nèi)容超出屏幕寬度顯示省略號(hào)
android開發(fā)中用textview顯示內(nèi)容時(shí),顯示內(nèi)容過(guò)多可能會(huì)折行或顯示不全,那樣效果很不好,我們可以用省略號(hào)顯示,下面看設(shè)置方法2014-02-02