调用系统录屏、截屏功能

安卓5.0及以上提供了支持截屏和录屏的API

布局如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:id="@+id/mainFrame"
    android:layout_height="match_parent">

    <Button android:layout_width="100dp"
        android:text="录屏"
        android:id="@+id/butview"
        android:layout_gravity="center"
        android:layout_height="60dp"/>
    <Button android:layout_width="100dp"
        android:text="截屏"
        android:layout_marginTop="100dp"
        android:id="@+id/capout"
        android:layout_gravity="center"
        android:layout_height="60dp"/>
    <ImageView
        android:id="@+id/img"
        android:layout_margin="60dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</FrameLayout>

主代码如下:

package com.example.leixiansheng.testactivity;

import android.Manifest;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.IBinder;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

	Button mButton, mCapButton;
	ImageView mImageView;
	private MediaProjectionManager projectionManager;
	private MediaProjection mediaProjection;
	private ScreenService recordService;
	private static int RECORD_REQUEST_CODE = 5;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
		mButton = (Button) findViewById(R.id.butview);
		mCapButton = (Button) findViewById(R.id.capout);
		mImageView = (ImageView) findViewById(R.id.img);
		askPermission();
		Intent intent = new Intent(this, ScreenService.class);
		bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
		mButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				//######## 录屏逻辑 ########
				if (recordService.isRunning()) {
					recordService.stopRecord();
					mButton.setText("录屏");
				} else {
					//这里是请求录屏权限
					Intent captureIntent = projectionManager
							.createScreenCaptureIntent();
					startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
				}
			}
		});
		mCapButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				Intent in = new Intent(MainActivity.this, CapoutActivity.class);
				startActivity(in);
			}
		});
	}

	private void askPermission() {
		if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
				!= PackageManager.PERMISSION_GRANTED) {
			ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 102);
		}
		if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
				!= PackageManager.PERMISSION_GRANTED) {
			ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 103);
		}
		if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
				!= PackageManager.PERMISSION_GRANTED) {
			ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 104);
		}
		Intent intent = null;
		if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
			intent = projectionManager.createScreenCaptureIntent();
			startActivityForResult(intent, 101);//正常情况是要执行到这里的,作用是申请捕捉屏幕
		} else {
			Toast.makeText(this, "Android版本太低,无法使用该功能",Toast.LENGTH_SHORT).show();
		}

	}


	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
			//######## 录屏逻辑 ########
			mediaProjection = projectionManager
					.getMediaProjection(resultCode, data);
			recordService.setMediaProject(mediaProjection);
			recordService.startRecord();
			mButton.setText("结束");
		}
	}


	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindService(mServiceConnection);
	}

	/**
	 * 绑定ScreenService
	 */
	private ServiceConnection mServiceConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName className, IBinder service) {
			DisplayMetrics metrics = new DisplayMetrics();
			getWindowManager().getDefaultDisplay().getMetrics(metrics);
			ScreenService.RecordBinder binder = (ScreenService.RecordBinder) service;
			recordService = binder.getRecordService();
			recordService
					.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
			mButton.setEnabled(true);
			mButton.setText(recordService.isRunning() ? "结束" : "开始");
		}


		@Override
		public void onServiceDisconnected(ComponentName arg0) {}
	};
}

ScreenService    记得Mainfest中注册

package com.example.leixiansheng.testactivity;

import android.app.Service;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * 项目名称:
 * 类描述: 录屏服务类
 */

public class ScreenService extends Service {
    private MediaRecorder mediaRecorder;
    private VirtualDisplay virtualDisplay;
    private boolean running;
    private int width = 720;
    private int height = 1080;
    private int dpi;
    private ImageReader mImageReader;
    private MediaProjection mediaProjection;


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


    @Override
    public void onCreate() {
        super.onCreate();
        running = false;
        mediaRecorder = new MediaRecorder();
    }


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


    @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;
    }


    /**
     * 开始录屏
     *
     * @return true
     */
    public boolean startRecord() {
        if (mediaProjection == null || running) {
            return false;
        }
        initRecorder();
        createVirtualDisplay();
        mediaRecorder.start();
        running = true;
        return true;
    }


    /**
     * 结束录屏
     *
     * @return true
     */
    public boolean stopRecord() {
        if (!running) {
            return false;
        }
        running = false;
        mediaRecorder.stop();
        mediaRecorder.reset();
        virtualDisplay.release();
        mediaProjection.stop();

        return true;
    }


    public void setMediaProjection(MediaProjection mediaProjection) {
        this.mediaProjection = mediaProjection;
    }


    /**
     * 初始化ImageRead参数
     */
    public void initImageReader() {
        if (mImageReader == null) {
            int maxImages = 2;
            mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, maxImages);
            createImageVirtualDisplay();
        }
    }


    /**
     * 创建一个录屏 Virtual
     */

    private void createVirtualDisplay() {
        virtualDisplay = mediaProjection
                .createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder
                        .getSurface(), null, null);
    }


    /**
     * 创建一个ImageReader Virtual
     */
    private void createImageVirtualDisplay() {
        virtualDisplay = mediaProjection
                .createVirtualDisplay("mediaprojection", width, height, dpi,
                        DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader
                        .getSurface(), null, null);
    }


    /**
     * 初始化保存屏幕录像的参数
     */
    private void initRecorder() {
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setOutputFile(
                getSavePath() + System.currentTimeMillis() + ".mp4");
        mediaRecorder.setVideoSize(width, height);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
        mediaRecorder.setVideoFrameRate(30);
        try {
            mediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取一个保存屏幕录像的路径
     *
     * @return path
     */
    public String getSavePath() {
        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;
                }
            }
            return rootDir;
        } else {
            return null;
        }
    }


    /**
     * 请求完权限后马上获取有可能为null,可以通过判断is null来重复获取。
     */
    public Bitmap getBitmap() {
        Bitmap bitmap = cutoutFrame();
        if (bitmap == null) {
            getBitmap();
        }
        return bitmap;
    }


    /**
     * 通过底层来获取下一帧的图像
     *
     * @return bitmap
     */
    public Bitmap cutoutFrame() {
        Image image = mImageReader.acquireLatestImage();
        if (image == null) {
            return null;
        }
        int width = image.getWidth();
        int height = image.getHeight();
        final Image.Plane[] planes = image.getPlanes();
        final ByteBuffer buffer = planes[0].getBuffer();
        int pixelStride = planes[0].getPixelStride();
        int rowStride = planes[0].getRowStride();
        int rowPadding = rowStride - pixelStride * width;
        Bitmap bitmap = Bitmap.createBitmap(width +
                rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
        bitmap.copyPixelsFromBuffer(buffer);
        return Bitmap.createBitmap(bitmap, 0, 0, width, height);
    }


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

CapoutActivity

package com.example.leixiansheng.testactivity;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

/**
 * 项目名称:
 * 类描述:截屏
 */

public class CapoutActivity extends Activity {
    Button mButton;
    ImageView mImageView;
    private MediaProjectionManager projectionManager;
    private MediaProjection mediaProjection;
    private ScreenService recordService;
    private static int RECORD_REQUEST_CODE = 5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_capout);
        projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        mButton = (Button) findViewById(R.id.butview);
        mImageView = (ImageView) findViewById(R.id.img);
        Intent intent = new Intent(this, ScreenService.class);
        bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
        Intent captureIntent = projectionManager.createScreenCaptureIntent();
        startActivityForResult(captureIntent, RECORD_REQUEST_CODE);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //########  截屏逻辑 ########
                Bitmap bitmap = recordService.getBitmap();
                mImageView.setImageBitmap(bitmap);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {

            //######## 截屏逻辑 ########
            mediaProjection = projectionManager.getMediaProjection(resultCode, data);
            recordService.setMediaProject(mediaProjection);
            recordService.initImageReader();

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            ScreenService.RecordBinder binder = (ScreenService.RecordBinder) service;
            recordService = binder.getRecordService();
            recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
            mButton.setEnabled(true);
            mButton.setText(recordService.isRunning() ? "结束" : "开始");
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {}
    };
}

参考与:https://blog.csdn.net/sinat_28238111/article/details/77979845

猜你喜欢

转载自blog.csdn.net/Mr_Leixiansheng/article/details/81031987
今日推荐