Android截屏程序

153 阅读1分钟

获取了MediaProject时

import android.content.Context;
import android.graphics.Bitmap;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class ScreenCapture {
    private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;

    private MediaProjection mMediaProjection;
    private VirtualDisplay mVirtualDisplay;
    private ImageReader mImageReader;
    private int mScreenWidth;
    private int mScreenHeight;
    private int mScreenDensity;

    public ScreenCapture(Context context, MediaProjection mediaProjection) {
        mMediaProjection = mediaProjection;

        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();

        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getRealMetrics(displayMetrics);

        mScreenWidth = displayMetrics.widthPixels;
        mScreenHeight = displayMetrics.heightPixels;
        mScreenDensity = displayMetrics.densityDpi;

        mImageReader = ImageReader.newInstance(mScreenWidth, mScreenHeight, PixelFormat.RGBA_8888, 1);
    }

    public void startCapture() {
        mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCapture",
                mScreenWidth, mScreenHeight, mScreenDensity,
                VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, null);
    }

    public void stopCapture() {
        if (mVirtualDisplay != null) {
            mVirtualDisplay.release();
            mVirtualDisplay = null;
        }

        if (mImageReader != null) {
            mImageReader.close();
            mImageReader = null;
        }

        if (mMediaProjection != null) {
            mMediaProjection.stop();
            mMediaProjection = null;
        }
    }

    public Bitmap getBitmap() {
        Image image = mImageReader.acquireLatestImage();
        if (image == null) {
            return 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 * mScreenWidth;

        Bitmap bitmap = Bitmap.createBitmap(mScreenWidth + rowPadding / pixelStride, mScreenHeight, Bitmap.Config.ARGB_8888);
        bitmap.copyPixelsFromBuffer(buffer);

        image.close();

        return bitmap;
    }

    public void saveBitmap(Bitmap bitmap) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault());
        String filename = "screenshot-" + dateFormat.format(new Date()) + ".png";

        File directory = new File(Environment.getExternalStorageDirectory() + "/Screenshots/");
        if (!directory.exists()) {
            directory.mkdirs();
        }

        File file = new File(directory, filename);

        try {
            FileOutputStream outputStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这个程序需要使用 MediaProjectionImageReader 类来截取屏幕并保存截屏图片。请注意,这个程序还需要相应的权限和用户授权才能运行。

未获取MediaProjection

public class ScreenshotActivity extends Activity { private static final int REQUEST_SCREENSHOT = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button btnScreenshot = findViewById(R.id.btn_screenshot);
    btnScreenshot.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            MediaProjectionManager mediaProjectionManager =
                    (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);

            Intent intent = mediaProjectionManager.createScreenCaptureIntent();
            startActivityForResult(intent, REQUEST_SCREENSHOT);
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SCREENSHOT) {
        if (resultCode == RESULT_OK) {
            MediaProjection mediaProjection =
                    ((MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE))
                            .getMediaProjection(resultCode, data);

            ImageReader imageReader = ImageReader.newInstance(
                    getWindow().getDecorView().getWidth(),
                    getWindow().getDecorView().getHeight(),
                    PixelFormat.RGBA_8888,
                    2);

            VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(
                    "Screenshot",
                    getWindow().getDecorView().getWidth(),
                    getWindow().getDecorView().getHeight(),
                    getResources().getDisplayMetrics().densityDpi,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                    imageReader.getSurface(),
                    null,
                    null);

            imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader) {
                    Bitmap bitmap = null;

                    try (Image image = reader.acquireLatestImage()) {
                        if (image != null) {
                            Image.Plane[] planes = image.getPlanes();
                            ByteBuffer buffer = planes[0].getBuffer();
                            int width = image.getWidth();
                            int height = image.getHeight();
                            int pixelStride = planes[0].getPixelStride();
                            int rowStride = planes[0].getRowStride();
                            int rowPadding = rowStride - pixelStride * width;
                            bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
                            bitmap.copyPixelsFromBuffer(buffer);
                            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        mediaProjection.stop();
                        virtualDisplay.release();
                        imageReader.close();
                    }

                    if (bitmap != null) {
                        String filename = "screenshot_" + System.currentTimeMillis() + ".png";
                        File file = new File(Environment.getExternalStorageDirectory(), filename);

                        try (FileOutputStream outputStream = new FileOutputStream(file)) {
                            bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);

                            Toast.makeText(ScreenshotActivity.this, "Screenshot saved to " + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, new Handler());
        }
    }
}

}