2

I'm using android MediaProjection for taking screenshot. The projection needs to be stopped after taking screenshot and virtual display should be released but VirtualDisplay.release() is not releasing the display. Here is the code to create display.

startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {

        sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);

        // display metrics
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        mDensity = metrics.densityDpi;
        mDisplay = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        mDisplay.getSize(size);
        mWidth = size.x;
        mHeight = size.y;

        // register media projection stop callback
        sMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);

        // register orientation change callback
        mOrientationChangeCallback = new OrientationChangeCallback(this);
        if (mOrientationChangeCallback.canDetectOrientation()) {
            mOrientationChangeCallback.enable();
        }


        // start capture reader
        mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 1);
        mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);
        mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);
    }
}

To stop the projection, I call sMediaProjection.stop(); and here is my MediaProjectionStopCallback implementation.

private class MediaProjectionStopCallback extends MediaProjection.Callback {
    @Override
    public void onStop() {
        Log.e("ScreenCapture", "stopping projection.");
        mHandler.post(new Runnable() {
            @Override
                public void run() {
                if (mVirtualDisplay != null) {
                    mVirtualDisplay.release();
                    Log.e("Virtual Display", "Released");
                }
                if (mImageReader != null)
                    mImageReader.setOnImageAvailableListener(null, null);    
                if (mOrientationChangeCallback != null)
                    mOrientationChangeCallback.disable();
                sMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);

                DisplayManager disp = (DisplayManager) getSystemService(DISPLAY_SERVICE);
                Display[] allDisplays = disp.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
                Log.e(TAG + "-Display", "Display Count  " + allDisplays.length);
                for (Display dl : allDisplays) {
                    Log.e(TAG + "-Display", "Display name: " + dl.getName() + " Display id: " + dl.getDisplayId());
                }
            }
        });

        //Toast.makeText(getApplicationContext(), "Projection Stopped", Toast.LENGTH_SHORT).show();
    }
}

This is the logcat.

03-02 14:52:55.925    8264-8732/codistan.pk.squeeze_me E/ScreenCapture﹕ stopping projection.
03-02 14:52:55.925    8264-8732/codistan.pk.squeeze_me E/Virtual Display﹕ Released
03-02 14:52:55.925    8264-8732/codistan.pk.squeeze_me E/codistan.pk.squeeze_me.ScreenCaptureActivity-Display﹕ Display Count  1
03-02 14:52:55.935    8264-8732/codistan.pk.squeeze_me E/codistan.pk.squeeze_me.ScreenCaptureActivity-Display﹕ Display name: screencap Display id: 1

I have double checked, the above onStop method is properly called as can be seen in the logcat. After releasing the display in onStop when I check the available displays, the virtual display is still listed as an available display. It affects the phone display and graphics and I can't play any video and the issue remains even after uninstalling the app untill I restart the phone. I have checked this link Android virtual display release does not remove display and searched a lot but nothing found helpful. Your help is highly appreciated.

Community
  • 1
  • 1
Abbas Ali
  • 41
  • 4
  • Actually release call will be queued and will be processed in the event queue. try dumping surfaceflinger after some times you called release on virtual display – nmxprime Mar 11 '16 at 12:56
  • Did you ever find an answer to this? – CamHart May 08 '20 at 19:31
  • Please find answer here https://stackoverflow.com/questions/65823544/call-release-did-not-work-after-creating-virtual-display – Jack Smother Jun 07 '21 at 21:13

1 Answers1

0

Try this?

if (mOrientationChangeCallback != null) {
    mOrientationChangeCallback.disable();
}
if (mVirtualDisplay != null) {
    mVirtualDisplay.release();
}
if (mMediaProjection != null) {
    mMediaProjection.stop();
}
if (mImageReader != null) {
    mImageReader.setOnImageAvailableListener(null, null);
    mImageReader.close();
}
reker
  • 2,063
  • 13
  • 12