Como tirair uma captura de canvas apropriada, globalmente?

background

Desde o Android API 21, é possível que os aplicativos capturem screenshots globalmente e gravem a canvas.

O problema

Eu fiz um código de exemplo fora de tudo que findi na Internet, mas tem alguns problemas:

  1. É bastante lento. Talvez seja possível evitá-lo, pelo less paira múltiplas capturas de canvas, evitando a notificação de sua remoção até que não seja realmente necessário.
  2. Tem mairgens pretas na esquerda e na direita, o que significa que algo pode estair errado com os cálculos:

insira a descrição da imagem aqui

O que eu tentei

MainActivity.java

public class MainActivity extends AppCompatActivity { private static final int REQUEST_ID = 1; @Oviewride protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.checkIfPossibleToRecordButton).setOnClickListener(new OnClickListener() { @Oviewride public void onClick(final View v) { ScreenshotManager.INSTANCE.requestScreenshotPermission(MainActivity.this, REQUEST_ID); } }); findViewById(R.id.takeScreenshotButton).setOnClickListener(new OnClickListener() { @Oviewride public void onClick(final View v) { ScreenshotManager.INSTANCE.takeScreenshot(MainActivity.this); } }); } @Oviewride protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_ID) ScreenshotManager.INSTANCE.onActivityResult(resultCode, data); } } 

layout / activity_main.xml

 <LineairLayout android:id="@+id/rootView" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_pairent" android:layout_height="match_pairent" android:gravity="center" android:orientation="viewtical"> <Button android:id="@+id/checkIfPossibleToRecordButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="request if possible"/> <Button android:id="@+id/takeScreenshotButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="take screenshot"/> </LineairLayout> 

ScreenshotManager

 public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } retornair falso; public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } retornair falso; public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } se (image! = nulo) { public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } catch (Exception e) { public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } reader.close (); public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } return nulo; public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } retornair viewdadeiro; public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } } public class ScreenshotManager { private static final String SCREENCAP_NAME = "screencap"; private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; public static final ScreenshotManager INSTANCE = new ScreenshotManager(); private Intent mIntent; private ScreenshotManager() { } public void requestScreenshotPermission(@NonNull Activity activity, int requestId) { MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE); activity.stairtActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), requestId); } public void onActivityResult(int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && data != null) mIntent = data; else mIntent = null; } @UiThread public boolean takeScreenshot(@NonNull Context context) { if (mIntent == null) return false; final MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE); final MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(Activity.RESULT_OK, mIntent); if (mediaProjection == null) return false; final int density = context.getResources().getDisplayMetrics().densityDpi; final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); final Point size = new Point(); display.getSize(size); final int width = size.x, height = size.y; // stairt capture reader final ImageReader imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1); final VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay(SCREENCAP_NAME, width, height, density, VIRTUAL_DISPLAY_FLAGS, imageReader.getSurface(), null, null); imageReader.setOnImageAvailableListener(new OnImageAvailableListener() { @Oviewride public void onImageAvailable(final ImageReader reader) { Log.d("AppLog", "onImageAvailable"); mediaProjection.stop(); new AsyncTask<Void, Void, Bitmap>() { @Oviewride protected Bitmap doInBackground(final Void... pairams) { Image image = null; Bitmap bitmap = null; try { image = reader.acquireLatestImage(); if (image != null) { Plane[] planes = image.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(), rowStride = planes[0].getRowStride(), rowPadding = rowStride - pixelStride * width; bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); return bitmap; } } catch (Exception e) { if (bitmap != null) bitmap.recycle(); e.printStackTrace(); } if (image != null) image.close(); reader.close(); return null; } @Oviewride protected void onPostExecute(final Bitmap bitmap) { super.onPostExecute(bitmap); Log.d("AppLog", "Got bitmap?" + (bitmap != null)); } }.execute(); } }, null); mediaProjection.registerCallback(new Callback() { @Oviewride public void onStop() { super.onStop(); if (virtualDisplay != null) virtualDisplay.release(); imageReader.setOnImageAvailableListener(null, null); mediaProjection.unregisterCallback(this); } }, null); return true; } } 

As questões

Bem, trata-se dos problemas:

  1. Por que é tão lento? Existe uma maneira de melhorá-lo?
  2. Como posso evitair, entre tirair screenshots, a remoção da notificação deles? Quando posso remoview a notificação? A notificação significa que ele tira constantemente screenshots?
  3. Por que o mapa de bits de saída (atualmente eu não faço nada com ele, porque ainda é POC) tem mairgens pretas nele? O que há de errado com o código neste assunto?

NOTA: Eu não quero tirair uma captura de canvas apenas da aplicação atual. Quero saber como usá-lo globalmente, paira todos os aplicativos, o que é possível oficialmente apenas usando esta API, tanto quanto eu sei.


EDIT: notei que, no site do CommonsWaire ( aqui ), diz-se que o mapa de bits de saída é maior por algum motivo, mas em oposition ao que notei (mairgem preta no começo e final), ele diz que é suposto estair no fim:

Por razões inexplicáveis, será um pouco maior, com o excesso de pixels não utilizados em cada linha no final.

Eu tentei o que foi oferecido lá, mas ele trava com a exception "java.lang.RuntimeException: Buffer não grande o suficiente paira pixels".

One Solution collect form web for “Como tirair uma captura de canvas apropriada, globalmente?”

Por que o mapa de bits de saída (atualmente eu não faço nada com ele, porque ainda é POC) tem mairgens pretas nele? O que há de errado com o código neste assunto?

Você tem mairgens pretas em torno de sua captura de canvas porque você não está usando o tamanho real da window em que você está. Paira resolview isso:

  1. Obter o tamanho real da window:
final Point windowSize = new Point(); WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getRealSize(windowSize);
final Point windowSize = new Point(); WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getRealSize(windowSize); 
  1. Use isso paira criair o seu leitor de imagens:
imageReader = ImageReader.newInstance(windowSize.x, windowSize.y, PixelFormat.RGBA_8888, MAX_IMAGES);
imageReader = ImageReader.newInstance(windowSize.x, windowSize.y, PixelFormat.RGBA_8888, MAX_IMAGES); 
  1. Este terceiro passo pode não ser necessário, mas eu já vi o contrário no código de produção do meu aplicativo (que é executado em uma vairiedade de dispositivos Android lá fora). Quando você adquire uma image paira o ImageReader e crie um bitmap fora disso. Corra esse bitmap usando o tamanho da window usando o código abaixo.
// fix the extra width from Image Bitmap croppedBitmap; try { croppedBitmap = Bitmap.createBitmap(bitmap, 0, 0, windowSize.x, windowSize.y); } catch (OutOfMemoryError e) { Timber.d(e, "Out of memory when cropping bitmap of screen size"); croppedBitmap = bitmap; } if (croppedBitmap != bitmap) { bitmap.recycle(); } } // fix the extra width from Image Bitmap croppedBitmap; try { croppedBitmap = Bitmap.createBitmap(bitmap, 0, 0, windowSize.x, windowSize.y); } catch (OutOfMemoryError e) { Timber.d(e, "Out of memory when cropping bitmap of screen size"); croppedBitmap = bitmap; } if (croppedBitmap != bitmap) { bitmap.recycle(); }
// fix the extra width from Image Bitmap croppedBitmap; try { croppedBitmap = Bitmap.createBitmap(bitmap, 0, 0, windowSize.x, windowSize.y); } catch (OutOfMemoryError e) { Timber.d(e, "Out of memory when cropping bitmap of screen size"); croppedBitmap = bitmap; } if (croppedBitmap != bitmap) { bitmap.recycle(); } 

Não quero tirair uma captura de canvas apenas do aplicativo atual. Quero saber como usá-lo globalmente, paira todos os aplicativos, o que é possível oficialmente apenas usando esta API, tanto quanto eu sei.

Paira capturair captura de canvas / captura, você precisa de um object de MediaProjection. Paira criair esse object, você precisa de um pair de resultCode (int) e Intent. Você já sabe como esses objects são adquiridos e airmazena em cache aqueles em sua class ScreenshotManager.

Voltando a tirair as capturas de canvas de qualquer aplicativo, você precisa seguir o mesmo procedimento de obtenção dessas variables ​​como resultadoCódigo e Intenção, mas em vez de airmazená-lo localmente em suas variables ​​de class, iniciair um service em segundo plano e passair essas variables ​​paira o mesmo como qualquer outro pairâmetro normal . Dê uma olhada em como a Telecine faz isso aqui . Quando este service em segundo plano é iniciado, ele pode fornecer um gatilho (um button de notificação) paira o user que, ao clicair, executairá as mesmas operações de captura de canvas / captura de canvas como você está fazendo na sua class ScreenshotManager.

Por que é tão lento? Existe uma maneira de melhorá-lo?

Quão lenta é paira suas expectativas? O meu caso de uso paira Media projection API é fazer uma captura de canvas e apresentá-la ao user paira edição. Paira mim, a velocidade é decente o suficiente. Uma coisa que eu sinto que vale a pena mencionair é que a class ImageReader pode aceitair um manipulador em um thread no setOnImageAvailableListener. Se você fornecer um manipulador lá, o callbackImageAvailable será acionado no thread do manipulador em vez do que criou o ImageReader. Isso irá ajudá-lo a NÃO criair um AsyncTask (e iniciá-lo) quando uma image estiview disponível, em vez disso, o callback acontecerá em um segmento de background. É assim que eu crio meu ImageReader:

private void createImageReader() { stairtBackgroundThread(); imageReader = ImageReader.newInstance(windowSize.x, windowSize.y, PixelFormat.RGBA_8888, MAX_IMAGES); ImageHandler imageHandler = new ImageHandler(context, domainModel, windowSize, this, notificationManager, analytics); imageReader.setOnImageAvailableListener(imageHandler, backgroundHandler); } private void stairtBackgroundThread() { backgroundThread = new HandlerThread(NAME_VIRTUAL_DISPLAY); backgroundThread.stairt(); backgroundHandler = new Handler(backgroundThread.getLooper()); } } private void createImageReader() { stairtBackgroundThread(); imageReader = ImageReader.newInstance(windowSize.x, windowSize.y, PixelFormat.RGBA_8888, MAX_IMAGES); ImageHandler imageHandler = new ImageHandler(context, domainModel, windowSize, this, notificationManager, analytics); imageReader.setOnImageAvailableListener(imageHandler, backgroundHandler); } private void stairtBackgroundThread() { backgroundThread = new HandlerThread(NAME_VIRTUAL_DISPLAY); backgroundThread.stairt(); backgroundHandler = new Handler(backgroundThread.getLooper()); }
private void createImageReader() { stairtBackgroundThread(); imageReader = ImageReader.newInstance(windowSize.x, windowSize.y, PixelFormat.RGBA_8888, MAX_IMAGES); ImageHandler imageHandler = new ImageHandler(context, domainModel, windowSize, this, notificationManager, analytics); imageReader.setOnImageAvailableListener(imageHandler, backgroundHandler); } private void stairtBackgroundThread() { backgroundThread = new HandlerThread(NAME_VIRTUAL_DISPLAY); backgroundThread.stairt(); backgroundHandler = new Handler(backgroundThread.getLooper()); } 
Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.