Android如何实现截屏功能

本文小编为大家详细介绍“Android如何实现截屏功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android如何实现截屏功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

成都创新互联公司服务项目包括三台网站建设、三台网站制作、三台网页制作以及三台网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,三台网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到三台省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

介绍

Android 5.0以后开放的录屏API,取视频中的一帧数据,这样就可以实现截屏

步骤

在activity中授权,在service中完成初始化并截图,当然可以后台定时截图,但是6.0系统会有内存溢出的bug

1:build.gradle

compileSdkVersion 21
    buildToolsVersion "27.0.3"

    defaultConfig {
        applicationId "com.aile.screenshot"
        multiDexEnabled true
        minSdkVersion 21
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }

2:在activity中授权

public void requestCapturePermission() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return;
        }
        MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_MEDIA_PROJECTION:
                if (resultCode == RESULT_OK && data != null) {
                    Service.setResultData(data);
                    startService(new Intent(this, Service.class));
                    finish();
                }
                break;
        }
    }

3:在service中初始化ImageReader,MediaProjection

private void createImageReader() {
        mImageReader = ImageReader.newInstance(mScreenWidth, mScreenHeight, PixelFormat.RGBA_8888, 1);
    }
 public void setUpMediaProjection() {
        mMediaProjection = getMediaProjectionManager().getMediaProjection(Activity.RESULT_OK, mResultData);
        }
    }

4:在service中完成截图重要步骤:

private void startScreenShot() {
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startVirtual();
            }
        }, 0);

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                startCapture();
            }
        }, 50);
    }
 public void startVirtual() {
        if (mMediaProjection != null) {
            virtualDisplay();
        } else {
            setUpMediaProjection();
            virtualDisplay();
        }
    }
 private void virtualDisplay() {
        mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",
                mScreenWidth, mScreenHeight, mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mImageReader.getSurface(), null, null);
    }

//异常处理的核心
private void startCapture() {
        Image image = null;
        try {
            image = mImageReader.acquireLatestImage();
        } catch (IllegalStateException e) {
            if (null != image) {
                image.close();
                image = null;
                image = mImageReader.acquireLatestImage();
            }
        }
        if (image == null) {
            startScreenShot();
        } else {
            SaveTask mSaveTask = new SaveTask();
            AsyncTaskCompat.executeParallel(mSaveTask, image);

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    stopVirtual();
                    tearDownMediaProjection();
                }
            }, 0);
        }
    }
public class SaveTask extends AsyncTask {
        @Override
        protected Bitmap 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();
            return bitmap;
        }

        @Override
        protected void onPostExecute(final Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //处理bitmap的业务代码
    }

5:Bitmap转IS流,指定区域截图

// 将Bitmap转换成InputStream
   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
   InputStream inputStream = new ByteArrayInputStream(bos.toByteArray());
//指定区域截图
   Rect mRect = new Rect(51, 74, 58, 62);
   BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, true);
   Bitmap bm = bitmapRegionDecoder.decodeRegion(mRect, null);

6:定时任务的处理

private Timer timer = new Timer();
 public void shootByTime() {
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                startScreenShot();
                super.handleMessage(msg);
            }
        };
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 1;
                handler.sendMessage(message);
            }
        }, 0, 100);
    }

7:横竖屏的处理

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == this.getResources().getConfiguration().ORIENTATION_PORTRAIT) {
            mRect = new Rect(51, 775, 745, 47);
        } else if (newConfig.orientation == this.getResources().getConfiguration().ORIENTATION_LANDSCAPE) {
            mRect = new Rect(54, 24, 545, 45);
        }
    }

读到这里,这篇“Android如何实现截屏功能”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注创新互联行业资讯频道。


本文题目:Android如何实现截屏功能
URL地址:http://scyanting.com/article/jjighh.html