2

I’m trying to capture emulator screen by using MediaProjection API and ImageReader. But it always generates black screen. The code is as follows.

@Override
public void onImageAvailable(ImageReader reader) {

    Log.i(TAG, "in OnImageAvailable");

    FileOutputStream fos = null;
    Bitmap bitmap = null;
    Image img = null;

    try {

        img = reader.acquireLatestImage();

        if (img != null) {

            Image.Plane[] planes = img.getPlanes();

            if (planes[0].getBuffer() == null) {
                return;
            }

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

            Log.v(TAG, "width: "+width+", height: "+height+", pixelStride: "+pixelStride+", rowStride: "+rowStride+", rowPadding: "+rowPadding);

            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;
            }

            String name = "/pyscreen" + count + ".png";
            count++;
            File file = new File(Environment.getExternalStorageDirectory(), name);
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            Log.i(TAG, "image saved in" + Environment.getExternalStorageDirectory() + name);
            img.close();
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (null != fos) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != bitmap) {
            bitmap.recycle();
        }
        if (null != img) {
            img.close();
        }
    }
}

I’ve already referred Take a screenshot using MediaProjection and Android ImageReader.acquireLatestImage returns invalid JPG\ reader-acquirelatestimage-returns-invalid-jpg They works fine for REAL devices, but not for emulators.

How can I take screen capture with emulators? My implementation has some problem? Do you have any ideas?

Thanks for all helps!

Community
  • 1
  • 1
  • Hi Taichiro, I'm having the same problem, but I haven't been able to get ANY Lollipop emulator to work at all. Have you tried this against an AVD created within Android Studio via the GUI, and gotten it to work? And if so, what specific settings did you use? I was able to get it to work with a a Marshmallow AVD. I'd also really like to know the root cause, to try and patch some of the other emulators out there if possible. – David E Aug 27 '16 at 23:43
  • Hi David! Try to set Graphics setting as "Software - GLES 2.0". It should work. Of course the emulators will be heavy with this option. Then you should decrease the resolution like WVGA. – Taichiro Suzuki Aug 28 '16 at 01:33
  • Hi Taichiro - I gave that a shot and it didn't seem to help.. have you confirmed this recently? And do you happen to have any code or an app that you could point me that that is confirmed working with Lollipop in SW? – David E Aug 28 '16 at 22:23
  • Hi David - Yes, I'm working on it and confirming that my code is working with Lollipop. My code is above. How did you create ImageReader? Mine is here. `ImageReader imageReader = ImageReader.newInstance(size.x, size.y, PixelFormat.RGBA_8888, 2);` I've refered following pages when I faced this problem, they might help you! http://www.andengine.org/forums/gles2/no-eglconfig-found-t6129-40.html#p33241 http://stackoverflow.com/questions/10179187/android-emulator-black-screen-with-gpu-emulation-yes http://stackoverflow.com/questions/11623930/problems-with-android-emulator-with-gpu-enabled – Taichiro Suzuki Aug 29 '16 at 01:36
  • Hi Taichiro - Yeah I created my ImageReader in exactly the same way. Also to be clear, my emulator(s) start fine, it is just that the ImageReader only captures black screenshots in lollipop. What is the OS you are running your emulators on, Linux? Windows? If you use Android Studio to create a new Lollipop Nexus 5X AVD emulator, can you capture non-black screenshots with it? Is the code you are using public anywhere? Thanks! – David E Aug 30 '16 at 04:31
  • 1st Question -> Mac OS 2nd Question -> Nop, as I wrote on below as an answer, Nexus* emulator has a bug or spesification that always generates black screen with MediaProjection API. 3rd Question -> Nop, it is private project that cannot be published. – Taichiro Suzuki Sep 02 '16 at 01:04

1 Answers1

0

Here, I could solve it by myself. I chose Nexus 5X as the test emulator but maybe it contains some bugs. (or specifications?) I created an emulator by command lines as follows.

[Terminal 0]
android update sdk -a -u -t sys-img-x86-android-23
android create avd -t 1 -b x86 -n "Emulator23_x86"
emulator -avd Emulator23_x86

[Terminal 1]
adb install -g path_to_apk/app-debug.apk
add pull /storage/sdcard/some.png .

It works fine completely. So, may be emulators that’s created by Android Studio’s device manager work fine as well. Then you should choose the emulators other than Nexus*, like WVGA.

Any way thanks for your guy’s helps!