0%

Android截屏去除黑边

  • Google 官方 sample
  • 主要是第44行 mActivity.getWindowManager().getDefaultDisplay().getRealMetrics 换成了 getRealMetrics
  • 然后利用了 Fragment 来感知 ActivityonActivityResult ,不用去每个 Activity

直接上代码:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class ScreenshotUtil {

public static final int REQUEST_MEDIA_PROJECTION = 1122 ;
private FragmentActivity mActivity;
private ImageReader mImageReader;
private Intent mResultData = null;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private ShotListener mShotListener;
private ScreenshotFragment mScreenshotFragment;
int width;
int height;
int dpi;

public ScreenshotUtil(FragmentActivity activity) {
this.mActivity = activity;
getScreenParams();
}

public void onActivityResult(int resultCode, Intent mResultData){
this.mResultData = mResultData;
mActivity.getSupportFragmentManager().beginTransaction().remove(mScreenshotFragment).commitNowAllowingStateLoss();
if (resultCode!= Activity.RESULT_OK){
mShotListener.onFailed("canceled");
return;
}
Handler handler=new Handler();//截屏必须在有looper的线程执行
handler.postDelayed(new Runnable() {
@Override
public void run() {
startCapture();
}
},200);//延时截屏,避免截屏提示弹框还没消失就开始截屏
}

@TargetApi(Build.VERSION_CODES.KITKAT)
private void createImageReader() {
mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 1);
}

private void getScreenParams(){
DisplayMetrics metric = new DisplayMetrics();
mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(metric);
width = metric.widthPixels;
height = metric.heightPixels;
dpi = metric.densityDpi;
}

public void startScreenShot(final ShotListener shotListener) {

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//5.0 之后才允许使用屏幕截图
shotListener.onFailed("系统版本不支持");
return;
}
if (!(this.mActivity instanceof FragmentActivity)){
shotListener.onFailed("context error");
return;
}
mShotListener=shotListener;
createImageReader();
mScreenshotFragment=new ScreenshotFragment(this);
((FragmentActivity) this.mActivity).getSupportFragmentManager().beginTransaction()
.add(mScreenshotFragment,"screenshot").commitNowAllowingStateLoss();
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager)
mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
mScreenshotFragment.startActivityForResult(
mediaProjectionManager.createScreenCaptureIntent(),
REQUEST_MEDIA_PROJECTION);
}

private MediaProjectionManager getMediaProjectionManager() {
return (MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}

private void startCapture() {
mMediaProjection = getMediaProjectionManager().getMediaProjection(Activity.RESULT_OK, mResultData);
mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mImageReader.getSurface(), null, null);

mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
if (mShotListener==null){
return;
}
Image image = mImageReader.acquireLatestImage();
if (image == null) {
mShotListener.onFailed("acquire Image is null");
} else {
Bitmap bitmap = covetBitmap(image);
if(bitmap != null){
mShotListener.onSuccess(bitmap);
}
}
stopVirtual();
mShotListener=null;
}
},null);
}

private Bitmap covetBitmap(Image image){
int width = image.getWidth();
int height = image.getHeight();
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 * width;
Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
image.close();
bitmap.recycle();
bitmap = null;
return resultBitmap;
}

public void stopVirtual() {
if (mVirtualDisplay == null) {
return;
}
mVirtualDisplay.release();
mVirtualDisplay = null;

tearDownMediaProjection();
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void tearDownMediaProjection() {
if (mMediaProjection != null) {
mMediaProjection.stop();
mMediaProjection = null;
}
}

public interface ShotListener {
void onFailed(String msg);
void onSuccess(Bitmap bitmap);
}

public class ScreenshotFragment extends Fragment {

private ScreenshotUtil mScreenshotUtil;

@SuppressLint("ValidFragment")
public ScreenshotFragment(ScreenshotUtil screenshotUtil){
mScreenshotUtil = screenshotUtil;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ScreenshotUtil.REQUEST_MEDIA_PROJECTION){
mScreenshotUtil.onActivityResult(resultCode,data);
}
mScreenshotUtil =null;
}


}

}