0

I want to share screen of the android with pc through Socket, the version of android don't matter.

What i found after a lot of search: MediaProjection.createVirtualDisplay to ImageReader to Bitmap and send it through Socket Network. What do you think?

It give a black frame and this error:

Attempt to invoke virtual method 'boolean android.os.Handler.post(java.lang.Runnable)' on a null object reference

I walked through this, this and this.

Here where i define ImageReader:

Point size = new Point();
        mDisplay.getSize(size);
        mWidth = size.x;
        mHeight = size.y;

mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
            mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
            mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);

ImageReader to Bitmap:

private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
        @Override
        public void onImageAvailable(ImageReader reader) {
            try {
                Image image = mImageReader.acquireLatestImage();
                final Image.Plane[] planes = image.getPlanes();
                final ByteBuffer buffer = planes[0].getBuffer();
                int offset = 0;
                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);
                image.close();
                if(bitmap!=null)
                    new Thread(new SendMessage(bitmap)).start();
}catch (Exception e) {
            e.printStackTrace();
        }

I also tried this but it didn't work:

 int width = img.getWidth();
                    int height = img.getHeight();
                    int pixelStride = planes[0].getPixelStride();
                    int rowStride = planes[0].getRowStride();
                    int rowPadding = rowStride - pixelStride * width;
                    byte[] newData = new byte[width * height * 4];

                    int offset = 0;
                    bitmap = Bitmap.createBitmap(metrics,width, height, Bitmap.Config.ARGB_8888);
                    ByteBuffer buffer = planes[0].getBuffer();
                    for (int i = 0; i < height; ++i) {
                        for (int j = 0; j < width; ++j) {
                            int pixel = 0;
                            pixel |= (buffer.get(offset) & 0xff) << 16;     // R
                            pixel |= (buffer.get(offset + 1) & 0xff) << 8;  // G
                            pixel |= (buffer.get(offset + 2) & 0xff);       // B
                            pixel |= (buffer.get(offset + 3) & 0xff) << 24; // A
                            bitmap.setPixel(j, i, pixel);
                            offset += pixelStride;
                        }
                        offset += rowPadding;
                    }

Send Bitmap through Socket, it works if i read the Bitmap from drawable:

 private class SendMessage implements Runnable{
        Bitmap image;
        public SendMessage( Bitmap im) {

            image = im;
        }

        public void run() {

            Socket socket = null;
            DataOutputStream dataOutputStream = null;
            DataInputStream dataInputStream = null;

            try {
                socket = new Socket("********", 8888);

                image.compress(Bitmap.CompressFormat.JPEG,50, socket.getOutputStream());



            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

Any advice will be welcome, Thanks If you have other way to share screen with pc over internet will be welcome also.

Community
  • 1
  • 1
  • You would be better off feeding the frames into the H.264 video encoder and sending the output. Much more efficient, and much less data to send across the network. A bit more complex to implement though. – fadden Apr 12 '16 at 21:59
  • Thanks @fadden that gives me un idea to expand my search, do you know how to implement H.264 video encoder with mediaprojection? – user2513825 Apr 13 '16 at 18:32
  • @user2513825 Did you get any solution to transfer the screenshare data over internet ? – Prasanth Ravi Oct 12 '22 at 12:24

0 Answers0