Android截屏

需求:后台周期性截屏

参考:https://www.jianshu.com/p/8d2302913960

重点:

1、ImageReader.newInstance中参数maxImages如果设置为1,则有时会取不到数据,原因不详。具体什么值合适,本人未详细测试,随意改成3

2、mImageReader.acquireLatestImage取相之前,先sleep(200),据说 mImageReader初始化需要时间。

3、只有Android 5.0到8.0才可用

代码:

private void initcaptureScreen(){
    Thread captureScreen = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                try {
                    requestScreenShot();
                    Thread.sleep(30000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    captureScreen.start();
}

public void requestScreenShot() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        mMediaProjectionManager = (MediaProjectionManager) this.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        try {
            if(LocalData!=null){
                doScreen(1,null);
            }else {
                startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
            }
        }catch (Exception ex){
            Log.d(TAG,ex.getMessage());
        }
    }
    else
    {
        Environment.toast(this, "系统版本过低,无法使用截屏功能。");
    }
}

private Intent LocalData=null;
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_MEDIA_PROJECTION: {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && resultCode == -1 && data != null) {
                LocalData = data;
                doScreen(0,LocalData);
            }else{
            }
        }
    }
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void doScreen(int mode,Intent localData){
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if(mode == 0) {
                mMediaProjection = mMediaProjectionManager.getMediaProjection(Activity.RESULT_OK, LocalData);
            }
        }

        mImageReader = ImageReader.newInstance(
                getScreenWidth(),
                getScreenHeight(),
                PixelFormat.RGBA_8888,
                3);
        startScreenShot(mode);
    }catch (Exception ex){
        Log.d(TAG,"doScreen:"+ex.getMessage());
    }
}
private int getScreenWidth() {
    return Resources.getSystem().getDisplayMetrics().widthPixels;
}

private int getScreenHeight() {
    return Resources.getSystem().getDisplayMetrics().heightPixels;
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void virtualDisplay() {
    mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
            getScreenWidth(),
            getScreenHeight(),
            Resources.getSystem().getDisplayMetrics().densityDpi,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            mImageReader.getSurface(),null, null);

}

@TargetApi(Build.VERSION_CODES.KITKAT)
public void startScreenShot(int mode) {
    virtualDisplay();
    if(mode == 0) {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    Image image = mImageReader.acquireLatestImage();
                                    AsyncTaskCompat.executeParallel(new ScreenShotSaveTask(), image);
                                }
                            },
                300);
    }else{
        try {
            Thread.sleep(200);
            Image image = mImageReader.acquireLatestImage();
            if(image == null){
                Log.d(TAG,"image is null");
            }else {
                AsyncTaskCompat.executeParallel(new ScreenShotSaveTask(), image);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

private class ScreenShotSaveTask extends AsyncTask<Image, Void, String> {
    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    protected String doInBackground(Image... params) {
        if (params == null || params.length < 1 || params[0] == null) {
            return null;
        }
        Image image = params[0];
        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);
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
        image.close();
        File fileImage = null;
        if (bitmap != null) {
            try {
                fileImage = RemoteServerFileManager.getScreenShotFile();

                if (!fileImage.exists()) {
                    fileImage.createNewFile();
                }
                FileOutputStream out = new FileOutputStream(fileImage);
                bitmap.compress(Bitmap.CompressFormat.PNG, 40, out);
                out.flush();
                out.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                fileImage = null;
            } catch (IOException e) {
                e.printStackTrace();
                fileImage = null;
            }
        }
        if (fileImage != null) {
            return fileImage.getPath();
        }
        return null;
    }
    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    protected void onPostExecute(String bitmapPath) {
        super.onPostExecute(bitmapPath);
        OnSavedFinish(bitmapPath);
        if (mVirtualDisplay != null) {
            mVirtualDisplay.release();
            mVirtualDisplay=null;
        }
    }
}
public void OnSavedFinish (String imagePath){
    
}

public static final int REQUEST_MEDIA_PROJECTION = 0x8000;
private MediaProjection mMediaProjection;
private ImageReader mImageReader;
private MediaProjectionManager mMediaProjectionManager;
private VirtualDisplay mVirtualDisplay;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值