//android 12之前的截图方式
/**
* 应用内截屏
*
* @param activity 截屏的activity
* @return 截屏图片
*/
public static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Bitmap bmp = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight());
view.destroyDrawingCache();
return bmp;
}
/**
* 获取系统界面截屏,需要系统权限(an12删除了该方法)
*
* @param mContext
* @return
*/
public static Bitmap screenshot(Context mContext) {
Display display = mContext.getDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getRealMetrics(metrics);
String surfaceClass = "android.view.SurfaceControl";
Class<?> surfaceClazz;
Bitmap bm = null;
try {
surfaceClazz = Class.forName(surfaceClass);
Method method = surfaceClazz.getMethod("screenshot", Rect.class,
int.class, int.class, int.class);
// 分辨率
Object[] values = new Object[]{
new Rect(0, 0, metrics.widthPixels, metrics.heightPixels),
metrics.widthPixels,
metrics.heightPixels,
display.getRotation()};
bm = (Bitmap) method.invoke(surfaceClazz, values);
} catch (Exception e) {
e.printStackTrace();
}
return bm;
}
/**
* Android12 获取界面截屏 需要framework.jar
*
* @param context
* @return
*/
public static Bitmap screenshot12(Context context) {
Bitmap bm = null;
final DisplayManager mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class));
final Display display = mDisplayManager.getDisplay(DEFAULT_DISPLAY);
DisplayMetrics metrics = new DisplayMetrics();
display.getRealMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
Rect crop = new Rect(0, 0, width, height);
final DisplayAddress address = display.getAddress();
if (!(address instanceof DisplayAddress.Physical)) {
Log.e("screenshot", "Skipping Screenshot - Default display does not have a physical address: "
+ display);
} else {
final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) address;
final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(
physicalAddress.getPhysicalDisplayId());
final SurfaceControl.DisplayCaptureArgs captureArgs =
new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
.setSourceCrop(crop)
.setSize(width, height)
.build();
final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
SurfaceControl.captureDisplay(captureArgs);
bm = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
}
return bm;
}
// 需在项目的build.gradle添加以下代码,不然找不到方法
allprojects {
String path = getRootDir().getAbsolutePath() + '/app/libs/framework.jar'
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
println(path)
options.compilerArgs << '-Xbootclasspath/p:' + path
}
}
}
screenshot12 方法来源:
frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
private Bitmap captureScreenshot(Rect crop) {
int width = crop.width();
int height = crop.height();
Bitmap screenshot = null;
final Display display = getDefaultDisplay();
final DisplayAddress address = display.getAddress();
if (!(address instanceof DisplayAddress.Physical)) {
Log.e(TAG, "Skipping Screenshot - Default display does not have a physical address: "
+ display);
} else {
final DisplayAddress.Physical physicalAddress = (DisplayAddress.Physical) address;
final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(
physicalAddress.getPhysicalDisplayId());
final SurfaceControl.DisplayCaptureArgs captureArgs =
new SurfaceControl.DisplayCaptureArgs.Builder(displayToken)
.setSourceCrop(crop)
.setSize(width, height)
.build();
final SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer =
SurfaceControl.captureDisplay(captureArgs);
screenshot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
}
return screenshot;
}
或许可以通过反射的方式调用该方法
编译源码,生成的framework.jar路径(暂时找到的这个是模块最全的):
out\soong\.intermediates\frameworks\base\framework-all\android_common\combined
改个名字即可,该目录jar包未必包含所有模块,可以从其他jar包复制进来