IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android录屏代码(录屏并生成mp4文件) -> 正文阅读

[移动开发]android录屏代码(录屏并生成mp4文件)

代码也是网上下的,不过一开始不能用,经过修改后可以使用了,现将代码发上来供大家参考(其中可能有些东西不需要,根据大家自己的需求再改吧):
首先是MainActivity(主页面):

import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private TextView mTvStart;
private TextView mTvEnd;
private TextView mTvTime;
private int REQUEST_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startService(new Intent(this, RecordUtil.class));
    CommonUtil.init(this);
    PermissionUtils.checkPermission(this);
    mTvStart = findViewById(R.id.tv_start);
    mTvStart.setOnClickListener(this);

    mTvTime = findViewById(R.id.tv_record_time);

    mTvEnd = findViewById(R.id.tv_end);
    mTvEnd.setOnClickListener(this);

    startScreenRecordService();
}
private ServiceConnection mServiceConnection;

/**
 * 开启录制 Service
 */
private void startScreenRecordService(){

    mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ScreenRecordService.RecordBinder recordBinder = (ScreenRecordService.RecordBinder) service;
            ScreenRecordService screenRecordService = recordBinder.getRecordService();
            ScreenUtil.setScreenService(screenRecordService);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    Intent intent = new Intent(this, ScreenRecordService.class);
    bindService(intent, mServiceConnection, BIND_AUTO_CREATE);

    ScreenUtil.addRecordListener(recordListener);
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    for (int temp : grantResults) {
        if (temp == PERMISSION_DENIED) {
            AlertDialog dialog = new AlertDialog
                    .Builder(this).setTitle("申请权限").setMessage("这些权限很重要").setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Toast.makeText(getApplicationContext(),"取消",Toast.LENGTH_LONG).show();
                }
            }).setPositiveButton("设置", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent();
                    intent.setAction(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    intent.setData(Uri.parse("package:" + MainActivity.this.getPackageName()));
                    MainActivity.this.startActivity(intent);
                }
            }).create();
            dialog.show();
            break;
        }
    }
}

private ScreenUtil.RecordListener recordListener = new ScreenUtil.RecordListener() {
    @Override
    public void onStartRecord() {

    }

    @Override
    public void onPauseRecord() {

    }

    @Override
    public void onResumeRecord() {

    }

    @Override
    public void onStopRecord(String stopTip) {
        Toast.makeText(getApplicationContext(),stopTip,Toast.LENGTH_LONG).show();
    }

    @Override
    public void onRecording(String timeTip) {
        mTvTime.setText(timeTip);
    }
};

@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 {
        Toast.makeText(getApplicationContext(),"拒绝录屏",Toast.LENGTH_LONG).show();
    }
}

@Override
public void onClick(View view) {
    switch (view.getId()){
        case R.id.tv_start:{
            ScreenUtil.startScreenRecord(this,REQUEST_CODE);
            break;
        }
        case R.id.tv_end:{
            ScreenUtil.stopScreenRecord(this);
            break;
        }
    }
}
}

然后是CommonUtil类:

import android.app.Activity;
import android.util.DisplayMetrics;
import android.view.Display;

public class CommonUtil {
private static int mScreenWidth;
private static int mScreenHeight;
private static int mScreenDpi;

public static void init(Activity activity){

    Display display = activity.getWindowManager().getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics(metrics);
    mScreenWidth = metrics.widthPixels;
    mScreenHeight = metrics.heightPixels;
    mScreenDpi = metrics.densityDpi;
}

public static int getScreenWidth(){
    return mScreenWidth;
}

public static int getScreenHeight(){
    return mScreenHeight;
}

public static int getScreenDpi(){
    return mScreenDpi;
}
}

然后是FileUtil类:

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.os.StatFs;
import android.provider.MediaStore;
import android.text.TextUtils;
import java.io.File;

public class FileUtil {
/**
 * 删除SD卡中的文件或目录
 *
 * @param path
 * @return
 */
public static boolean deleteSDFile(String path) {
    return deleteSDFile(path, false);
}

/**
 * 删除SD卡中的文件或目录
 *
 * @param path
 * @param deleteParent true为删除父目录
 * @return
 */
public static boolean deleteSDFile(String path, boolean deleteParent) {
    if (TextUtils.isEmpty(path)) {
        return false;
    }

    File file = new File(path);
    if (!file.exists()) {
        //不存在
        return true;
    }
    return deleteFile(file, deleteParent);
}

/**
 * @param file
 * @param deleteParent true为删除父目录
 * @return
 */
public static boolean deleteFile(File file, boolean deleteParent) {
    boolean flag = false;
    if (file == null) {
        return flag;
    }
    if (file.isDirectory()) {
        //是文件夹
        File[] files = file.listFiles();
        if (files.length > 0) {
            for (int i = 0; i < files.length; i++) {
                flag = deleteFile(files[i], true);
                if (!flag) {
                    return flag;
                }
            }
        }
        if (deleteParent) {
            flag = file.delete();
        }
    } else {
        flag = file.delete();
    }
    file = null;
    return flag;
}

/**
 * 添加到媒体数据库
 *
 * @param context 上下文
 */
public static Uri fileScanVideo(Context context, String videoPath, int videoWidth, int videoHeight,
                                int videoTime) {

    File file = new File(videoPath);
    if (file.exists()) {

        Uri uri = null;

        long size = file.length();
        String fileName = file.getName();
        long dateTaken = System.currentTimeMillis();

        ContentValues values = new ContentValues(11);
        values.put(MediaStore.Video.Media.DATA, videoPath); // 路径;
        values.put(MediaStore.Video.Media.TITLE, fileName); // 标题;
        values.put(MediaStore.Video.Media.DURATION, videoTime * 1000); // 时长
        values.put(MediaStore.Video.Media.WIDTH, videoWidth); // 视频宽
        values.put(MediaStore.Video.Media.HEIGHT, videoHeight); // 视频高
        values.put(MediaStore.Video.Media.SIZE, size); // 视频大小;
        values.put(MediaStore.Video.Media.DATE_TAKEN, dateTaken); // 插入时间;
        values.put(MediaStore.Video.Media.DISPLAY_NAME, fileName);// 文件名;
        values.put(MediaStore.Video.Media.DATE_MODIFIED, dateTaken / 1000);// 修改时间;
        values.put(MediaStore.Video.Media.DATE_ADDED, dateTaken / 1000); // 添加时间;
        values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");

        ContentResolver resolver = context.getContentResolver();

        if (resolver != null) {
            try {
                uri = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
            } catch (Exception e) {
                e.printStackTrace();
                uri = null;
            }
        }

        if (uri == null) {
            MediaScannerConnection.scanFile(context, new String[]{videoPath}, new String[]{"video/*"}, new MediaScannerConnection.OnScanCompletedListener() {
                @Override
                public void onScanCompleted(String path, Uri uri) {

                }
            });
        }

        return uri;
    }

    return null;
}

/**
 * SD卡存在并可以使用
 */
public static boolean isSDExists() {
    return Environment.getExternalStorageState().equals(
            Environment.MEDIA_MOUNTED);
}

/**
 * 获取SD卡的剩余容量,单位是Byte
 *
 * @return
 */
public static long getSDFreeMemory() {
    try {
        if (isSDExists()) {
            File pathFile = Environment.getExternalStorageDirectory();
            // Retrieve overall information about the space on a filesystem.
            // This is a Wrapper for Unix statfs().
            StatFs statfs = new StatFs(pathFile.getPath());
            // 获取SDCard上每一个block的SIZE
            long nBlockSize = statfs.getBlockSize();
            // 获取可供程序使用的Block的数量
            // long nAvailBlock = statfs.getAvailableBlocksLong();
            long nAvailBlock = statfs.getAvailableBlocks();
            // 计算SDCard剩余大小Byte
            long nSDFreeSize = nAvailBlock * nBlockSize;
            return nSDFreeSize;
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return 0;
}
}

接下来是PermissionUtils类:

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class PermissionUtils {
/**
 * 获取打开摄像机的权限,录音,文件读写
 *
 * @param activity
 */
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) {
            //动态申请
            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;
}
}

接下来是RecordUtil类:

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.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.HandlerThread;
import android.os.IBinder;

import androidx.annotation.Nullable;

import java.io.File;
import java.io.IOException;

public class RecordUtil extends Service {
//    private static RecordUtil recordUtil = null;
private MediaProjection mediaProjection;

private MediaRecorder mediaRecorder;
private VirtualDisplay virtualDisplay;
private boolean running;
private int width = 320;
private int height = 420;
private int dpi;
private Context context;

public static int current = 0;

public RecordUtil(){

}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return new RecordBinder();
}

@Override
public void onCreate() {
    super.onCreate();
    HandlerThread serviceThread = new HandlerThread("service_thread",
            android.os.Process.THREAD_PRIORITY_BACKGROUND);
    serviceThread.start();
    running = false;
    mediaRecorder = new MediaRecorder();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return  START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
}

public void setMediaProject(MediaProjection project) {
    mediaProjection = project;
}

public boolean isRunning() {
    return running;
}

public void setConfig(int width, int height, int dpi) {
    this.width = width;
    this.height = height;
    this.dpi = dpi;
}

public boolean startRecord(String temp) {
    if(mediaRecorder != null) {
        if (mediaProjection == null || running) {
            return false;
        }
        try {
            initRecorder(temp);
            createVirtualDisplay();
            mediaRecorder.start();
            running = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return true;
}

public boolean stopRecord() {
    if(mediaRecorder != null) {
        if (!running) {
            return false;
        }
        try {
            running = false;
            mediaRecorder.stop();
            mediaRecorder.reset();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                virtualDisplay.release();
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    mediaProjection.stop();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    return true;
}

public boolean release(){
    if(mediaRecorder != null && hasLollipop()) {
        if (!running) {
            return false;
        }
        try {
            running = false;
            mediaRecorder.stop();
            mediaRecorder.reset();
            virtualDisplay.release();
            mediaProjection.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return true;
}

public static boolean hasLollipop(){
    return Build.VERSION.SDK_INT >= 21;
}

private void createVirtualDisplay() {

    if(hasLollipop()) {
        virtualDisplay = mediaProjection.createVirtualDisplay("MainScreen", width, height, dpi,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);
    }
}

private void initRecorder(String temp) {
    if(mediaRecorder != null) {
        try {
            // mediaRecorder.setAudioSource(MediaRecorder.AudioSource.);
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mediaRecorder.setOutputFile(getsaveDirectory() + temp + ".mp4");
            //mediaRecorder.setVideoSize(width, height);
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            // mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
            mediaRecorder.setVideoEncodingBitRate(1024 * 1024);
            mediaRecorder.setVideoFrameRate(18);
            //设置要捕获的视频的宽度和高度
            //mSurfaceHolder.setFixedSize(320, 240);//最高只能设置640x480
            mediaRecorder.setVideoSize(width, height);//最高只能设置640x480
            //mediaRecorder.setOrientationHint(90);
            //mediaRecorder.setMaxDuration(30*1000);
            mediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static String getsaveDirectory() {
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "ScreenRecord" + "/";

        File file = new File(rootDir);
        if (!file.exists()) {
            if (!file.mkdirs()) {
                return null;
            }
        }

        //Toast.makeText(context, rootDir, Toast.LENGTH_SHORT).show();

        return rootDir;
    } else {
        return null;
    }
}

/**
 * 递归删除文件
 * @param file
 */
public static void recursionDeleteFile(File file){
    try {
        if(file.isFile()){
            file.delete();
            return;
        }
        if(file.isDirectory()){
            File[] childFile = file.listFiles();
            if(childFile == null || childFile.length == 0){
                file.delete();
                return;
            }
            for(File f : childFile){
                recursionDeleteFile(f);
            }
            file.delete();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public class RecordBinder extends Binder {
    public RecordUtil getRecordService() {
        return RecordUtil.this;
    }
}
}

接下来是ScreenRecordService类:

import android.annotation.TargetApi;
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.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import java.io.File;
import java.io.IOException;

public class ScreenRecordService extends Service implements Handler.Callback{
private MediaProjectionManager mProjectionManager;
private MediaProjection mMediaProjection;
private MediaRecorder mMediaRecorder;
private VirtualDisplay mVirtualDisplay;

private boolean mIsRunning;
private int mRecordWidth = CommonUtil.getScreenWidth();
private int mRecordHeight = CommonUtil.getScreenHeight();
private int mScreenDpi = CommonUtil.getScreenDpi();

private int mResultCode;
private Intent mResultData;

//录屏文件的保存地址
private String mRecordFilePath;

private Handler mHandler;
//已经录制多少秒了
private int mRecordSeconds = 0;

private static final int MSG_TYPE_COUNT_DOWN = 110;
@Nullable
@Override
public IBinder onBind(Intent intent) {
    return new RecordBinder();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

@Override
public void onCreate() {
    super.onCreate();
    System.out.println("111=====onCreate=======");
    mIsRunning = false;
    mMediaRecorder = new MediaRecorder();
    mHandler = new Handler(Looper.getMainLooper(),this);
}

@Override
public void onDestroy() {
    super.onDestroy();
}

public boolean isReady(){
    return  mMediaProjection != null && mResultData != null;
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void clearRecordElement(){
    clearAll();
    if (mMediaRecorder != null){
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mMediaRecorder = null;
    }
    mResultData = null;
    mIsRunning =false;
}

public boolean ismIsRunning() {
    return mIsRunning;
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void setResultData(int resultCode, Intent resultData){
    mResultCode = resultCode;
    mResultData = resultData;

    mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    if (mProjectionManager != null){
        mMediaProjection = mProjectionManager.getMediaProjection(mResultCode,mResultData);
    }
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean startRecord() {
    if ( mIsRunning) {
        return false;
    }
    if (mMediaProjection == null){
        mMediaProjection = mProjectionManager.getMediaProjection(mResultCode,mResultData);

    }

    setUpMediaRecorder();
    createVirtualDisplay();
    mMediaRecorder.start();

    ScreenUtil.startRecord();
    //最多录制三分钟
    mHandler.sendEmptyMessageDelayed(MSG_TYPE_COUNT_DOWN,1000);

    mIsRunning = true;

    return true;
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean stopRecord(String tip) {

    if (!mIsRunning) {
        return false;
    }
    mIsRunning = false;

    try {
        mMediaRecorder.stop();
        mMediaRecorder.reset();
        mMediaRecorder = null;
        mVirtualDisplay.release();
        mMediaProjection.stop();

    }catch (Exception e){
        e.printStackTrace();
        mMediaRecorder.release();
        mMediaRecorder = null;
    }

    mMediaProjection = null;

    mHandler.removeMessages(MSG_TYPE_COUNT_DOWN);
    ScreenUtil.stopRecord(tip);

    if (mRecordSeconds <= 2 ){

        FileUtil.deleteSDFile(mRecordFilePath);
    }else {
        //通知系统图库更新
        FileUtil.fileScanVideo(this,mRecordFilePath,mRecordWidth,mRecordHeight,mRecordSeconds);
    }

    mRecordSeconds = 0;

    return true;
}

public void pauseRecord(){
    if (mMediaRecorder != null ){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mMediaRecorder.pause();
        }
    }
}

public void resumeRecord(){
    if (mMediaRecorder != null ){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            mMediaRecorder.resume();
        }
    }
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void createVirtualDisplay() {
    mVirtualDisplay = mMediaProjection.createVirtualDisplay("MainScreen", mRecordWidth, mRecordHeight, mScreenDpi,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setUpMediaRecorder() {

    mRecordFilePath = getSaveDirectory()  + "/videotest/luping.mp4";
    if (mMediaRecorder == null){
        mMediaRecorder = new MediaRecorder();
    }
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    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();
    }
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void clearAll(){
    if (mMediaProjection != null){
        mMediaProjection.stop();
        mMediaProjection = null;
    }
}

public String getRecordFilePath(){
    return mRecordFilePath;
}

public String getSaveDirectory() {

    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

        return Environment.getExternalStorageDirectory().getAbsolutePath();
    } else {
        return null;
    }
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean handleMessage(Message msg) {
    switch (msg.what){

        case MSG_TYPE_COUNT_DOWN:{

            String str = null;
            boolean enough = FileUtil.getSDFreeMemory() / (1024* 1024) < 4;
            if (enough){
                //空间不足,停止录屏
                str = getString(R.string.record_space_tip);
                stopRecord(str);
                mRecordSeconds = 0;
                break;
            }

            mRecordSeconds++;
            int minute = 0, second = 0;
            if (mRecordSeconds >= 60 ){
                minute = mRecordSeconds / 60;
                second = mRecordSeconds % 60;
            } else {
                second = mRecordSeconds;
            }
            ScreenUtil.onRecording("0"+minute+":"+ (second < 10 ? "0"+second :second+"") );
            if (mRecordSeconds < 5 * 60 ){
                mHandler.sendEmptyMessageDelayed(MSG_TYPE_COUNT_DOWN,1000);
            } else if (mRecordSeconds == 5 * 60 ){
                str = getString(R.string.record_time_end_tip);
                stopRecord(str);
                mRecordSeconds = 0;
            }

            break;
        }
    }
    return true;
}

public class RecordBinder extends Binder {
    public ScreenRecordService getRecordService() {
        return ScreenRecordService.this;
    }
}
}

最后一个类是ScreenUtil类:

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.util.Log;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class ScreenUtil {
private static ScreenRecordService s_ScreenRecordService;

private static List<RecordListener> s_RecordListener = new ArrayList<>();

private static List<OnPageRecordListener> s_PageRecordListener = new ArrayList<>();

//true,录制结束的提示语正在显示
public static boolean s_IsRecordingTipShowing = false;

/**
 * 录屏功能 5.0+ 的手机才能使用
 * @return
 */
public static boolean isScreenRecordEnable(){
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ;
}

public static void setScreenService(ScreenRecordService screenService){
    s_ScreenRecordService = screenService;
}

public static void clear(){
    if ( isScreenRecordEnable() && s_ScreenRecordService != null){
        s_ScreenRecordService.clearAll();
        s_ScreenRecordService = null;

    }

    if (s_RecordListener != null && s_RecordListener.size() > 0){
        s_RecordListener.clear();
    }

    if (s_PageRecordListener != null && s_PageRecordListener.size() > 0 ){
        s_PageRecordListener.clear();
    }
}

/**
 * 开始录制
 */
public static void startScreenRecord(Activity activity,int requestCode) {
    if (isScreenRecordEnable()){

        if (s_ScreenRecordService != null && !s_ScreenRecordService.ismIsRunning()){

            if (!s_ScreenRecordService.isReady()){

                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){
                        //存在录屏授权的Activity

                        activity.startActivityForResult(intent,requestCode);
                    }else {

                        Toast.makeText(activity, R.string.can_not_record_tip,Toast.LENGTH_SHORT).show();
                    }
                }

            } else {
                s_ScreenRecordService.startRecord();

            }

        }
    }

}

/**
 * 获取用户允许录屏后,设置必要的数据
 * @param resultCode
 * @param resultData
 */
public static void setUpData(int resultCode,Intent resultData) throws Exception{

    if (isScreenRecordEnable()){

        if (s_ScreenRecordService != null && !s_ScreenRecordService.ismIsRunning()){

            s_ScreenRecordService.setResultData(resultCode,resultData);
            s_ScreenRecordService.startRecord();

        }

    }
}

/**
 * 停止录制
 */
public static void stopScreenRecord(Context context){
    if (isScreenRecordEnable()){
        if (s_ScreenRecordService != null && s_ScreenRecordService.ismIsRunning()){
            String str = context.getString(R.string.record_video_tip);
            s_ScreenRecordService.stopRecord(str);
        }
    }
}

/**
 * 获取录制后的文件地址
 * @return
 */
public static String getScreenRecordFilePath(){

    if (isScreenRecordEnable() && s_ScreenRecordService!= null) {
        Log.d("111","录制文件地址==" + s_ScreenRecordService.getRecordFilePath());
        return s_ScreenRecordService.getRecordFilePath();
    }
    return null;

}

/**
 * 判断当前是否在录制
 * @return
 */
public static boolean isCurrentRecording(){
    if (isScreenRecordEnable() && s_ScreenRecordService!= null) {
        return s_ScreenRecordService.ismIsRunning();
    }
    return false;
}

/**
 * true,录制结束的提示语正在显示
 * @return
 */
public static boolean isRecodingTipShow(){
    return s_IsRecordingTipShowing;
}

public static void setRecordingStatus(boolean isShow){
    s_IsRecordingTipShowing = isShow;
}


/**
 * 系统正在录屏,app 录屏会有冲突,清理掉一些数据
 */
public static void clearRecordElement(){

    if (isScreenRecordEnable()){
        if (s_ScreenRecordService != null ){
            s_ScreenRecordService.clearRecordElement();
        }
    }
}

public static void addRecordListener(RecordListener listener){

    if (listener != null && !s_RecordListener.contains(listener)){
        s_RecordListener.add(listener);
    }

}

public static void removeRecordListener(RecordListener listener){
    if (listener != null && s_RecordListener.contains(listener)){
        s_RecordListener.remove(listener);
    }
}

public static void addPageRecordListener( OnPageRecordListener listener){

    if (listener != null && !s_PageRecordListener.contains(listener)){
        s_PageRecordListener.add(listener);
    }
}

public static void removePageRecordListener( OnPageRecordListener listener){

    if (listener != null && s_PageRecordListener.contains(listener)){
        s_PageRecordListener.remove(listener);
    }
}

public static void onPageRecordStart(){
    if (s_PageRecordListener!= null && s_PageRecordListener.size() > 0 ){
        for (OnPageRecordListener listener : s_PageRecordListener){
            listener.onStartRecord();
        }
    }
}


public static void onPageRecordStop(){
    if (s_PageRecordListener!= null && s_PageRecordListener.size() > 0 ){
        for (OnPageRecordListener listener : s_PageRecordListener){
            listener.onStopRecord();
        }
    }
}

public static void onPageBeforeShowAnim(){
    if (s_PageRecordListener!= null && s_PageRecordListener.size() > 0 ){
        for (OnPageRecordListener listener : s_PageRecordListener){
            listener.onBeforeShowAnim();
        }
    }
}

public static void onPageAfterHideAnim(){
    if (s_PageRecordListener!= null && s_PageRecordListener.size() > 0 ){
        for (OnPageRecordListener listener : s_PageRecordListener){
            listener.onAfterHideAnim();
        }
    }
}

public static void startRecord(){
    if (s_RecordListener.size() > 0 ){
        for (RecordListener listener : s_RecordListener){
            listener.onStartRecord();
        }
    }
}

public static void pauseRecord(){
    if (s_RecordListener.size() > 0 ){
        for (RecordListener listener : s_RecordListener){
            listener.onPauseRecord();
        }
    }
}

public static void resumeRecord(){
    if (s_RecordListener.size() > 0 ){
        for (RecordListener listener : s_RecordListener){
            listener.onResumeRecord();
        }
    }
}

public static void onRecording(String timeTip){
    if (s_RecordListener.size() > 0 ){
        for (RecordListener listener : s_RecordListener){
            listener.onRecording(timeTip);
        }
    }
}

public static void stopRecord(String stopTip){
    if (s_RecordListener.size() > 0 ){
        for (RecordListener listener : s_RecordListener){
            listener.onStopRecord( stopTip);
        }
    }
}

public interface RecordListener{


    void onStartRecord();
    void onPauseRecord();
    void onResumeRecord();
    void onStopRecord(String stopTip);
    void onRecording(String timeTip);
}


public interface OnPageRecordListener {

    void onStartRecord();
    void onStopRecord();

    void onBeforeShowAnim();
    void onAfterHideAnim();
}
}

然后是MainActivity的布局文件(这里网上那人用的TestView做点击,我就没改,只是试功能能不能实现,大家可以改成Button):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
    android:id="@+id/tv_record_time"
    android:text="0:00"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_margin="20dp"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_start"
        android:text="开始录制"
        android:textSize="21dp"
        android:clickable="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_end"
        android:text="结束录制"
        android:textSize="21dp"
        android:clickable="true"
        android:layout_marginLeft="50dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

</LinearLayout>

然后在AndroidManifest.xml中注册服务:
在这里插入图片描述
然后在AndroidManifest.xml中写权限(我这里很多权限用不上):
在这里插入图片描述
然后在strings.xml中添加一些String:
在这里插入图片描述
targetSdkVersion改成28以下就行
在这里插入图片描述
这样就可以运行啦~~

原作是:https://blog.csdn.net/nazicsdn/article/details/102553033?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2aggregatepagefirst_rank_v2~rank_aggregation-16-102553033.pc_agg_rank_aggregation&utm_term=android+%E5%BD%95%E5%B1%8F%E5%AE%9E%E7%8E%B0%E4%BB%A3%E7%A0%81&spm=1000.2123.3001.4430

我只是在他的基础上做了修改

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:46:00  更:2021-07-29 11:46:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 18:48:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码