Skip to content

Instantly share code, notes, and snippets.

@aslamanver
Created August 12, 2020 08:03
Show Gist options
  • Save aslamanver/e68463f8d452b40428f29532dac9b11c to your computer and use it in GitHub Desktop.
Save aslamanver/e68463f8d452b40428f29532dac9b11c to your computer and use it in GitHub Desktop.
Screenshot Provider - Android Java
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;
import java.nio.ByteBuffer;
public class ScreenshotProvider {
public static final int REQUEST_CODE = 5555;
public interface Listener {
void onInit();
void onScreenshot(Bitmap bitmap);
int screenshotInterval();
void onStop();
}
Listener listener;
Activity activity;
MediaProjectionManager mProjectionManager;
MediaProjection mProjection;
MediaRecorder mRecorder;
VirtualDisplay mVirtualDisplay;
ImageReader mImageReader;
Handler screenHandler = new Handler();
Runnable screenRunnable;
public ScreenshotProvider(Activity activity, Listener listener) {
this.activity = activity;
this.listener = listener;
mProjectionManager = (MediaProjectionManager) this.activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
this.mProjection = mProjectionManager.getMediaProjection(resultCode, data);
listener.onInit();
return true;
}
return false;
}
public boolean init() {
if (mProjection == null) {
activity.startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
return false;
}
return true;
}
public boolean getScreenshot() {
WindowManager wm = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
final DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
Point size = new Point();
display.getRealSize(size);
final int mWidth = size.x;
final int mHeight = size.y;
int mDensity = metrics.densityDpi;
screenRunnable = new Runnable() {
@Override
public void run() {
mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);
final Handler handler = new Handler();
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * metrics.widthPixels;
// create bitmap
Bitmap bmp = Bitmap.createBitmap(metrics.widthPixels + (int) ((float) rowPadding / (float) pixelStride), metrics.heightPixels, Bitmap.Config.ARGB_8888);
bmp.copyPixelsFromBuffer(buffer);
image.close();
reader.close();
Bitmap realSizeBitmap = Bitmap.createBitmap(bmp, 0, 0, metrics.widthPixels, bmp.getHeight());
bmp.recycle();
/* [realSizeBitmap] */
listener.onScreenshot(realSizeBitmap);
screenHandler.postDelayed(screenRunnable, listener.screenshotInterval());
mVirtualDisplay.release();
if (listener.screenshotInterval() == 0) {
stopScreenShare();
}
}
}, handler);
if (mProjection != null) {
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
mVirtualDisplay = mProjection.createVirtualDisplay("screen-mirror", mWidth, mHeight, mDensity, flags, mImageReader.getSurface(), null, handler);
}
}
};
screenHandler.post(screenRunnable);
return true;
}
public void stopScreenShare() {
new Handler().post(new Runnable() {
@Override
public void run() {
if (mProjection != null) {
mProjection.stop();
}
mProjection = null;
screenHandler.removeCallbacks(screenRunnable);
listener.onStop();
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment