Created
August 12, 2020 08:03
-
-
Save aslamanver/e68463f8d452b40428f29532dac9b11c to your computer and use it in GitHub Desktop.
Screenshot Provider - Android Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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