android 截屏

2020-09-17  本文已影响0人  proud2008
package cn.helmet.activity.callSingle;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

import androidx.annotation.RequiresApi;

import com.xin.common.keep.local.XUtils;
import com.xin.common.utils.LogUtils;
import com.xin.common.utils.PhoneInfo;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Date;

public class ScreenUtils {
    private final int RequestCodeForScreen = 9986;
    private final int mWidth, mHeight, mDensity;
    Activity activity;
    ScreenCallback callback;
    Handler handler;

    public ScreenUtils(Activity activity) {
        this.activity = activity;
        handler = new Handler();
        DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
        WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        mDensity = metrics.densityDpi;
        mWidth = size.x;
        mHeight = size.y;
    }

    public void doScreen(ScreenCallback callback) {
        if (Build.VERSION.SDK_INT >= 21) {
            this.callback = callback;
            MediaProjectionManager systemService = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
            Intent intent = systemService.createScreenCaptureIntent();
            activity.startActivityForResult(intent, RequestCodeForScreen);
        } else {
            Log.e("TAG", "版本过低,无法截屏");
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RequestCodeForScreen && data != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                parseData(data);
            }
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void parseData(Intent data) {
        ImageReader mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 1);
        MediaProjectionManager projectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        MediaProjection mMediaProjection = projectionManager.getMediaProjection(Activity.RESULT_OK, data);
        VirtualDisplay mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
                mWidth, mHeight, mDensity,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mImageReader.getSurface(), new ScreenVirtualCallBack(mImageReader), null);
        mImageReader.setOnImageAvailableListener(new ImageAvailableListener(mVirtualDisplay), null);
    }

    private void log(String s) {
        LogUtils.log("ScreenUtils", s);
    }

    private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
        VirtualDisplay mVirtualDisplay;

        public ImageAvailableListener(VirtualDisplay mVirtualDisplay) {
            this.mVirtualDisplay = mVirtualDisplay;
        }

        @Override
        public void onImageAvailable(ImageReader reader) {
            log("onImageAvailable() called with: reader = [" + reader + "]");
            try {
                Image image = reader.acquireLatestImage();
                if (image != null) {
                    String name = String.valueOf(System.currentTimeMillis());
                    File file = new File(XUtils.getDir(activity, "snap"), name + ".png");//将要保存图片的路径
                    saveJpeg(image, file);
                    image.close();
                    reader.close();
                    if (file.exists() && callback != null) {
                        callback.onScreenSuccess(file);
                    }
                }
                mVirtualDisplay.release();
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }

    private void saveJpeg(Image image, File file) {
        Image.Plane[] planes = image.getPlanes();
        ByteBuffer buffer = planes[0].getBuffer();
        int pixelStride = planes[0].getPixelStride();
        int rowStride = planes[0].getRowStride();
        int rowPadding = rowStride - pixelStride * mWidth;

        Bitmap bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
        bitmap.copyPixelsFromBuffer(buffer);
        try {
            java.io.BufferedOutputStream bos = new java.io.BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 回调
     */
    public static interface ScreenCallback {
        void onScreenSuccess(File f);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private class ScreenVirtualCallBack extends VirtualDisplay.Callback {
        ImageReader mImageReader;

        public ScreenVirtualCallBack(ImageReader mImageReader) {
            this.mImageReader = mImageReader;
        }

        @Override
        public void onPaused() {
            super.onPaused();
            log("onPaused() called");
        }

        @Override
        public void onResumed() {
            super.onResumed();
            log("onResumed() called");
        }

        @Override
        public void onStopped() {
            super.onStopped();
            log("onStopped() called");
        }
    }
}

上一篇 下一篇

猜你喜欢

热点阅读