Android uses reflection mechanism to call screen capture method and screen width and height acquisition method

  • 2021-12-11 19:01:10
  • OfStack

If you want to take screenshots in the application, you can directly call getDrawingCache method of View, but there is no status bar for screenshots of this method. If you want to take screenshots of the whole screen, you have to realize it yourself.

There is also a method that can call the screenshot method hidden by the system to take a screenshot, and the screenshot of this method is the whole screen.
Screenshot by calling SurfaceControl. screenshot ()/Surface. screenshot (), SurfaceControl is used when API is greater than 17, and Surface is used when Level is less than or equal to 17, but the screenshot method is hidden, so it needs to be called with reflection.
The parameters that this method needs to pass in are width and height, so you need to get the width and height of the whole screen. There are three commonly used methods.

Get screen width and height

Method 1


int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();

This method will prompt that it is outdated, and the latter two are recommended.

Method 2


DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;

Method 3


Resources resources = this.getResources();
DisplayMetrics dm = resources.getDisplayMetrics();
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;

Reflection calls screen capture method


public Bitmap screenshot() {
  Resources resources = this.getResources();
  DisplayMetrics dm = resources.getDisplayMetrics();

  String surfaceClassName = "";
  if (Build.VERSION.SDK_INT <= 17) {
    surfaceClassName = "android.view.Surface";
  } else {
    surfaceClassName = "android.view.SurfaceControl";
  }
 
  try {
    Class<?> c = Class.forName(surfaceClassName);
    Method method = c.getMethod("screenshot", new Class[]{int.class, int.class});
    method.setAccessible(true);
    return (Bitmap) method.invoke(null, dm.widthPixels, dm.heightPixels);
  } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | ClassNotFoundException e) {
    e.printStackTrace();
  }
  return null;
}

The Bitmap object returned at last is the truncated image.

Required permissions


<uses-permission android:name="android.permission.READ_FRAME_BUFFER"/>

Calling screen capture requires system permission, so applications that cannot be signed by the system will report errors.


Related articles: