Android实现屏幕共享功能封装(原理:通过手机实时截图,并转化为视频流)

最近太过于焦虑,晚上都睡不着啊,谁能告诉我怎么赚大钱啊?何以解忧?唯有暴富啊。555555555555555

 

好了话不多说,直接进入正题:

1、MediaProjectionManager //获取MediaProjection

2、MediaProjection //获取屏幕内容

3、ImageReader  //通过这个类我们可以把Surface转换成图片

首先初始化相关的东西啦

 public void initScreenHelper(Activity activity) {
//获取到屏幕的宽高
 this.mActivity = activity;
        WindowManager windowManager = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
        this.mWidth = windowManager.getDefaultDisplay().getWidth() / 2;
        this.mHeight = windowManager.getDefaultDisplay().getHeight() / 2;


 DisplayMetrics displayMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        this.mScreenDensity = displayMetrics.densityDpi / 3;


        this.mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 5);
        this.mMediaManager = (MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);


}

Android截屏的api是Android系统5.0以后开放的api,切需要用户手动开启后才能使用。所以我们先要获取屏幕使用权限。

private boolean startScreenCapture() {
        if (mMediaProjection != null) {//已经获取到权限并且获取到了mMediaProjection
            setUpVirtualDisplay();
            return true;
        } else if (mResultCode != 0 && mResultData != null) {//获取到了权限
            setUpMediaProjection();
            setUpVirtualDisplay();
            return true;
        } else {//没有获取到权限,开启权限弹窗,并在onActivityResult回调里获取对应的数据
            Log.e(TAG, "Requesting confirmation");
            mActivity.startActivityForResult(mMediaManager.createScreenCaptureIntent(), REQUEST_CODE_PROJECTION);
            return false;
        }
    }


/**
     * 设置VirtualDisplay,屏幕截图载体
     */
    private void setUpVirtualDisplay() {
//获取到的数据就已经储存在ImageReader中的surface中
        if (mVirtualDisplay == null) {
            mVirtualDisplay = mMediaProjection.createVirtualDisplay("AnyChatScreenHelper",
                    mWidth, mHeight, mScreenDensity,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                    mImageReader.getSurface(), null, null);
        }
    }


 private void setUpMediaProjection() {
        if (mMediaProjection == null)
            mMediaProjection = mMediaManager.getMediaProjection(mResultCode, mResultData);
    }

 

最后就是拿到相关数据了

/**
     * 处理截图数据
     * Image.Plane中的 buffer 数据并不是完全是Bitmap所需要的,需要注意下面3点

       * 1. Image 设置的图片格式与Bitmap设置的必须一致

       * 2. 缓冲数据存在行间距,所以我们必须去除这些间距

        *3. Image 使用后必须调用image.close();关闭,否则再次使用会报错
     */
    private void handleCapture() {
        if (mActivity != null && mActivity.isFinishing()) {
            closeCapture();
            return;
        }
        if (mImageReader == null) {
            return;
        }
        Image image = mImageReader.acquireLatestImage();
        if (image == null) {
            open();
            return;
        }
        int width = image.getWidth();
        int height = image.getHeight();
        final Image.Plane[] planes = image.getPlanes();
        if (planes == null) {
            image.close();
            return;
        }
        final ByteBuffer buffer = planes[0].getBuffer();
        if (buffer == null) {
            image.close();
            return;
        }
        int pixelStride = planes[0].getPixelStride();
        int rowStride = planes[0].getRowStride();
        int rowPadding = rowStride - pixelStride * width;
        mBitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
        mBitmap.copyPixelsFromBuffer(buffer);
        mBitmap = Bitmap.createBitmap(mBitmap, 0, 0, width, height);
        image.close();
        if (mBitmap != null) {//将数据转换为数据流
            int bytes = mBitmap.getByteCount();
            ByteBuffer buf = ByteBuffer.allocate(bytes);
            mBitmap.copyPixelsToBuffer(buf);
            if (!mBitmap.isRecycled()) {
                mBitmap.recycle();
                mBitmap = null;
            }
            if (buf == null) {
                return;
            }
            byte[] datas = buf.array();
            if (datas == null || datas.length == 0) {
                return;
            }
            if (mPostRunable == null) {
                mPostRunable = new PostRunable();
            }
            mPostRunable.setDatas(datas);
            if (cachedThreadPool != null) {
                cachedThreadPool.submit(mPostRunable);
            }
            if (mHandler != null) {
                mHandler.sendEmptyMessageDelayed(MSG_SCREEN_CAPTURE, 100);
            }
        }
    }

 

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值