Android录屏功能

310 阅读1分钟
public class ScreenRecorderService extends Service {
    private static final int REQUEST_CODE_SCREEN_CAPTURE = 1;
    private MediaProjectionManager mediaProjectionManager;
    private MediaProjection mediaProjection;
    private VirtualDisplay virtualDisplay;
    private MediaRecorder mediaRecorder;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE_SCREEN_CAPTURE);
        return START_NOT_STICKY;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_SCREEN_CAPTURE && resultCode == RESULT_OK) {
            mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
            mediaRecorder = new MediaRecorder();
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mediaRecorder.setOutputFile(getOutputFile());
            mediaRecorder.setVideoSize(1280, 720);
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            try {
                mediaRecorder.prepare();
            } catch (IOException e) {
                e.printStackTrace();
            }
            virtualDisplay = mediaProjection.createVirtualDisplay("ScreenRecorder",
                    1280, 720, getResources().getDisplayMetrics().densityDpi,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                    mediaRecorder.getSurface(), null, null);
            mediaRecorder.start();
        }
    }

    private String getOutputFile() {
        String path = Environment.getExternalStorageDirectory().getPath() + "/record.mp4";
        File file = new File(path);
        if (file.exists()) {
            file.delete();
        }
        return path;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mediaRecorder != null) {
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
        if (virtualDisplay != null) {
            virtualDisplay.release();
        }
        if (mediaProjection != null) {
            mediaProjection.stop();
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
import android.app.Presentation;
import android.content.Context;
import android.os.Bundle;
import android.view.Display;
import android.widget.TextView;

public class TestPresentation extends Presentation {
    private TextView textView;
    public TestPresentation(Context context, Display display) {
        super(context, display);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.presentation_layout);
        textView = findViewById(R.id.text_view);
    }
    public void changeText() {
        textView.setText("Updated text");
    }
}


class MainActivity : AppCompatActivity() {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDisplayManager = (DisplayManager)this.getSystemService(Context.DISPLAY_SERVICE);
        getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //测试ImageReader
                testVirtualDisplay();
            }
        });
        imageView = findViewById(R.id.image);
    }


    private void testVirtualDisplay(){
        final int screenWidth = outMetrics.widthPixels;
        final int screenHeight = outMetrics.heightPixels;
        ImageReader imageReader = ImageReader.newInstance(
                screenWidth,
                screenHeight,
                PixelFormat.RGBA_8888, 1);

        //创建虚拟屏,传入ImageReader的Surface
        VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay("testVirtualDisplay",
                WIDTH, HEIGHT, DENSITY, imageReader.getSurface(), DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION);

        //设置回调
        imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            //回调中获取Surface的渲染数据
            @Override
            public void onImageAvailable(ImageReader reader) {
                mImageReaderLock.lock();
                try {
                    // Get the latest buffer.
                    Image image = reader.acquireLatestImage();
                    if (image != null) {
                        Image.Plane[] planes = image.getPlanes();
                    	ByteBuffer buffer = planes[0].getBuffer();
                    	int pixelStride = planes[0].getPixelStride();
                    	int rowStride = planes[0].getRowStride();
                    	int rowPadding = rowStride - pixelStride * screenWidth;
                    	Bitmap bitmap = Bitmap.createBitmap(screenWidth + rowPadding / pixelStride,
                            screenHeight, Bitmap.Config.ARGB_8888);
                    	bitmap.copyPixelsFromBuffer(buffer);

                    	//virtualDisplay.release();
                    	imageView.setImageBitmap(bitmap);
                    	image.close();
                    }
                } finally {
                    mImageReaderLock.unlock();
                }
            }
        }, handler);
        DisplayManager displayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE);
        Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
        if (presentationDisplays.length > 0) {
            Display display = presentationDisplays[0];
            //TestPresentation指定显示在虚拟屏
            TestPresentation presentation = new TestPresentation(this, display);
            presentation.show();
            
            findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //更新TestPresentation的UI
                    presentation.changeText();
                }
            });
        }
    }
}