加入收藏 | 设为首页 |

火竞猜下载-Android三种方法截取恣意界面屏幕

海外新闻 时间: 浏览:297 次

一、运用MediaProjectionManager

Android5.0之后,敞开截取屏幕的API,也便是运用MediaProjectionManager创立VirtualDisplay,传入与ImageReader相关的Surface,这样就能够从ImageReader中获取到Image,然后把Image的像素数组拷贝到Bitmap,假如要保存为图片,就用得到的Bitmap紧缩为JPEG格局的图片。

首先是运用startActi火竞猜下载-Android三种方法截取恣意界面屏幕vityForResult主张录屏的恳求:

private void startScreenShot(){
WindowManager wi火竞猜下载-Android三种方法截取恣意界面屏幕ndowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null) {
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
width = displayMetrics.widthPixels;
height = displayMetrics.heightPixels;
dpi = displayMetrics.densityDpi;
}
mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECT火竞猜下载-Android三种方法截取恣意界面屏幕ION_SERVICE);
if (mediaProjectionManager != null) {
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), 123);
}
}

在得到用户授权录屏后,在onActivityResult中获取MediaProjection-->VirtualDisplay-->ImagReader-->Image-->Bitmap:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
if (mediaProjection != null){
getBitmap(mediaProjection);
}
}private void getBitmap(MediaProjection mediaProjection){
ImageReader imageReader = ImageReader.newInstance(width, h火竞猜下载-Android三种方法截取恣意界面屏幕eight, PixelFormat.RGBA_8888, 3);
mediaProjection.createVirtualDisplay("screen_shot",
width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
imageReader.getSurface(), null, null);
imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireNextImage();
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);
String filePath = Environment.getExternalStorageDirectory().getPath() + "/hello.jpg";
//bitmap保存为图片
saveBitmap(bitmap, filePath);
image.close();
}
}, null);
}private void saveBitmap(Bitmap bitmap, String filePath){
try {
FileOutputStream outputStream = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

长处:不必体系签涉县天气预报名,不依靠体系底层API;

缺陷:弹出承认框,需求用户授权录屏;

二、运用SurfaceControl

从上面剖析可知,MediaProjectionManager录屏依靠Surface,剖析Surface源码后,发现Surface其实是调用SurfaceControl,也便是说能够用SurfaceControl走捷径去截屏。其实体系结构层的截屏也是调用SurfaceControl。可是,因为SurfaceControl归于体系API,对用户不敞开,咱们无法直接调用。提到这儿,我们应该都想到,用反射机制来调用。

正确的调用办法是这样的:

Bitmap bitmap = SurfaceControl.screenshot(width, height);

经过体系源码,能够知道它在Android.view.SurfaceControl途径下。已然途径、类、办法、参数都知道了,反射就没问题:

//运用反射调用截屏
private void screenShotByReflect(){
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
float[] dims = { mDisplayMetrics.widthPixels,
mDisplayMetrics.heightPixels };
try {
Class
Method method = demo.getDeclaredMethod("screenshot", int.class,int.class);
mScreenBitmap = (Bitmap) method.invoke(null,(int) dims[0],(int) dims[1]);
} catch (Exception e) {
e.printStackTrace();
}
}

在调用截屏之前,判别屏幕是否发作旋转:

private Bitmap takeScreenshot() {
mDisplay.getRealMetrics(mDisplayMetrics);
float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
float degrees = getDegreesForRotation(mDisplay.getRotation());
boolean requiresRotation = (degrees > 0);
//假如屏幕发作旋转,经过matrix旋转回来
if (requiresRotation) {
mDisplayMatrix.reset();
mDisplayMatrix.preRotate(-degrees);
mDisplayMatrix.mapPoints(dims);
dims[0] = Math.abs(dims[0]);
dims[1] = Math.abs(dims[1]);
}
//调用截屏
screenShotByReflect();
return mScreenBitmap;
}

长处:不必弹框授权,不必体系签名;

缺陷:运用反射机制,假如体系API或许办法发作更改,导致无法调用;

三、运用screencap的adb指令

指令行是这样的:adb shell screencap -p file_path

在代码中履行,就不必adb shell,直接screencap -p file_path,调用Runtime的进程来履行:

public static void screenShotByShell(String filePath){
String shotCmd = "screencap -p " + filePath + " \n";
try {
Runtime.getRuntime().exec(shotCmd);
} catch (IOException e) {
e.printStackTrace();
}
}

长处:代码简略,直接获取到图片;

缺陷:需求体系签名;

以上三种截屏办法,我们能够依据运用场景来运用。假如是用户app,需求接连录屏,主张选用MediaProjectionManager;假如是期望得到单个Bitmap,那么能够用SurfaceControl;假如是体系app,而且期望得到图片,首选screencap的adb指令行。

学习以上技能有哪些门槛和条件?有没有免费材料呢?

只需你心里有清晰的方针和巴望:我一定要进入大厂,一定要成为Android架构师。那么学历,年限都不能阻挠你。正常来说BAT社招门槛是3年开发经历,本科或许以上学历,除非你技能特别凶猛才干打破。

创造不易喜爱的话记住点击+重视哦