2016-03-02 37 views
1

我使用android MediaProjection進行截圖。屏幕截圖後需要停止投影,virtual display應該被釋放,但VirtualDisplay.release()沒有釋放顯示。這是創建顯示的代碼。Android VirtualDisplay.release()不發佈顯示

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

要停止投影,我打電話sMediaProjection.stop();,這裏是我的MediaProjectionStopCallback實現。

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

這是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 

我有雙重檢查,上述onStop方法被適當地稱爲可在logcat中可以看出。在檢查可用顯示屏後,在onStop中釋放顯示後,虛擬顯示仍被列爲可用顯示。 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.我已檢查此鏈接Android virtual display release does not remove display並搜索了很多,但沒有任何發現有幫助。非常感謝您的幫助。

+0

實際上,發佈呼叫將排隊並將在事件隊列中處理。嘗試在虛擬顯示器上調用發佈之後拋棄surfaceflinger – nmxprime

回答

0

試試這個嗎?

if (mOrientationChangeCallback != null) { 
    mOrientationChangeCallback.disable(); 
} 
if (mVirtualDisplay != null) { 
    mVirtualDisplay.release(); 
} 
if (mMediaProjection != null) { 
    mMediaProjection.stop(); 
} 
if (mImageReader != null) { 
    mImageReader.setOnImageAvailableListener(null, null); 
    mImageReader.close(); 
}