Android開發(fā)實現(xiàn)錄屏小功能
最近開發(fā)中,要實現(xiàn)錄屏功能,查閱相關(guān)資料,發(fā)現(xiàn)調(diào)用 MediaProjectionManager的api 實現(xiàn)錄屏功能即可:
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
public class RecordScreenActivity extends Activity {
private boolean isRecord = false;
private int mScreenWidth;
private int mScreenHeight;
private int mScreenDensity;
private int REQUEST_CODE_PERMISSION_STORAGE = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestPermission();
getScreenBaseInfo();
startScreenRecord();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1000) {
if (resultCode == RESULT_OK) {
//獲得錄屏權(quán)限,啟動Service進(jìn)行錄制
Intent intent = new Intent(this, ScreenRecordService.class);
intent.putExtra("resultCode", resultCode);
intent.putExtra("resultData", data);
intent.putExtra("mScreenWidth", mScreenWidth);
intent.putExtra("mScreenHeight", mScreenHeight);
intent.putExtra("mScreenDensity", mScreenDensity);
startService(intent);
finish();
}
}
}
//start screen record
private void startScreenRecord() {
//Manages the retrieval of certain types of MediaProjection tokens.
MediaProjectionManager mediaProjectionManager =
(MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
//Returns an Intent that must passed to startActivityForResult() in order to start screen capture.
Intent permissionIntent = mediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(permissionIntent, 1000);
}
/**
* 獲取屏幕基本信息
*/
private void getScreenBaseInfo() {
//A structure describing general information about a display, such as its size, density, and font scaling.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mScreenWidth = metrics.widthPixels;
mScreenHeight = metrics.heightPixels;
mScreenDensity = metrics.densityDpi;
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private void requestPermission() {
if (Build.VERSION.SDK_INT >= 23) {
String[] permissions = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
};
for (String str : permissions) {
if (this.checkSelfPermission(str) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(permissions, REQUEST_CODE_PERMISSION_STORAGE);
return;
}
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==REQUEST_CODE_PERMISSION_STORAGE){
startScreenRecord();
}
}
}
service 里面進(jìn)行相關(guān)錄制工作
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.support.annotation.Nullable;
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by dzjin on 2018/1/9.
*/
public class ScreenRecordService extends Service {
private int resultCode;
private Intent resultData=null;
private MediaProjection mediaProjection=null;
private MediaRecorder mediaRecorder=null;
private VirtualDisplay virtualDisplay=null;
private int mScreenWidth;
private int mScreenHeight;
private int mScreenDensity;
private Context context=null;
@Override
public void onCreate() {
super.onCreate();
}
/**
* Called by the system every time a client explicitly starts the service by calling startService(Intent),
* providing the arguments it supplied and a unique integer token representing the start request.
* Do not call this method directly.
* @param intent
* @param flags
* @param startId
* @return
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
resultCode=intent.getIntExtra("resultCode",-1);
resultData=intent.getParcelableExtra("resultData");
mScreenWidth=intent.getIntExtra("mScreenWidth",0);
mScreenHeight=intent.getIntExtra("mScreenHeight",0);
mScreenDensity=intent.getIntExtra("mScreenDensity",0);
mediaProjection=createMediaProjection();
mediaRecorder=createMediaRecorder();
virtualDisplay=createVirtualDisplay();
mediaRecorder.start();
}catch (Exception e) {
e.printStackTrace();
}
/**
* START_NOT_STICKY:
* Constant to return from onStartCommand(Intent, int, int): if this service's process is
* killed while it is started (after returning from onStartCommand(Intent, int, int)),
* and there are no new start intents to deliver to it, then take the service out of the
* started state and don't recreate until a future explicit call to Context.startService(Intent).
* The service will not receive a onStartCommand(Intent, int, int) call with a null Intent
* because it will not be re-started if there are no pending Intents to deliver.
*/
return Service.START_NOT_STICKY;
}
//createMediaProjection
public MediaProjection createMediaProjection(){
/**
* Use with getSystemService(Class) to retrieve a MediaProjectionManager instance for
* managing media projection sessions.
*/
return ((MediaProjectionManager)getSystemService(Context.MEDIA_PROJECTION_SERVICE))
.getMediaProjection(resultCode,resultData);
/**
* Retrieve the MediaProjection obtained from a succesful screen capture request.
* Will be null if the result from the startActivityForResult() is anything other than RESULT_OK.
*/
}
private MediaRecorder createMediaRecorder(){
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String filePathName= Environment.getExternalStorageDirectory()+"/"+simpleDateFormat.format(new Date())+".mp4";
//Used to record audio and video. The recording control is based on a simple state machine.
MediaRecorder mediaRecorder=new MediaRecorder();
//Set the video source to be used for recording.
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
//Set the format of the output produced during recording.
//3GPP media file format
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//Sets the video encoding bit rate for recording.
//param:the video encoding bit rate in bits per second.
mediaRecorder.setVideoEncodingBitRate(5*mScreenWidth*mScreenHeight);
//Sets the video encoder to be used for recording.
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//Sets the width and height of the video to be captured.
mediaRecorder.setVideoSize(mScreenWidth,mScreenHeight);
//Sets the frame rate of the video to be captured.
mediaRecorder.setVideoFrameRate(60);
try{
//Pass in the file object to be written.
mediaRecorder.setOutputFile(filePathName);
//Prepares the recorder to begin capturing and encoding data.
mediaRecorder.prepare();
}catch (Exception e){
e.printStackTrace();
}
return mediaRecorder;
}
private VirtualDisplay createVirtualDisplay(){
/**
* name String: The name of the virtual display, must be non-empty.This value must never be null.
width int: The width of the virtual display in pixels. Must be greater than 0.
height int: The height of the virtual display in pixels. Must be greater than 0.
dpi int: The density of the virtual display in dpi. Must be greater than 0.
flags int: A combination of virtual display flags. See DisplayManager for the full list of flags.
surface Surface: The surface to which the content of the virtual display should be rendered, or null if there is none initially.
callback VirtualDisplay.Callback: Callback to call when the virtual display's state changes, or null if none.
handler Handler: The Handler on which the callback should be invoked, or null if the callback should be invoked on the calling thread's main Looper.
*/
/**
* DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
* Virtual display flag: Allows content to be mirrored on private displays when no content is being shown.
*/
return mediaProjection.createVirtualDisplay("mediaProjection",mScreenWidth,mScreenHeight,mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,mediaRecorder.getSurface(),null,null);
}
@Override
public void onDestroy() {
super.onDestroy();
if(virtualDisplay!=null){
virtualDisplay.release();
virtualDisplay=null;
}
if(mediaRecorder!=null){
mediaRecorder.stop();
mediaRecorder=null;
}
if(mediaProjection!=null){
mediaProjection.stop();
mediaProjection=null;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
錄屏功能就這么實現(xiàn)了,有什么不妥之處,敬請留言討論。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android中使用RecyclerView實現(xiàn)下拉刷新和上拉加載
RecyclerView 是Android L版本中新添加的一個用來取代ListView的SDK,它的靈活性與可替代性比listview更好。這篇文章主要介紹了Android中使用RecyclerView實現(xiàn)下拉刷新和上拉加載的相關(guān)資料,需要的朋友可以參考下2016-03-03
Android 狀態(tài)欄虛擬導(dǎo)航鍵透明效果的實現(xiàn)方法
這篇文章主要介紹了Android 狀態(tài)欄虛擬導(dǎo)航鍵透明效果的實現(xiàn)方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03
Android開發(fā)中MotionEvent坐標(biāo)獲取方法分析
這篇文章主要介紹了Android開發(fā)中MotionEvent坐標(biāo)獲取方法,結(jié)合實例形式分析了MotionEvent獲取坐標(biāo)的相關(guān)函數(shù)使用方法與相關(guān)注意事項,需要的朋友可以參考下2016-02-02
Android編程實現(xiàn)3D旋轉(zhuǎn)效果實例
這篇文章主要介紹了Android編程實現(xiàn)3D旋轉(zhuǎn)效果的方法,基于Android的Camera類實現(xiàn)坐標(biāo)變換達(dá)到圖片3D旋轉(zhuǎn)效果,需要的朋友可以參考下2016-01-01
Android 解決dialog彈出時無法捕捉Activity的back事件問題
這篇文章主要介紹了Android 解決dialog彈出時無法捕捉Activity的back事件問題的相關(guān)資料,需要的朋友可以參考下2016-11-11
Android開發(fā)之基于RecycleView實現(xiàn)的頭部懸浮控件
RecyclerView是一種類似于ListView的一個滑動列表,但是RecyclerView和ListView相比,RecyclerView比ListView更好,這篇文章重點給大家介紹基于RecycleView實現(xiàn)的頭部懸浮控件,感興趣的朋友一起看看吧2019-10-10

