andorid12 截图方法 screenshot

//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包复制进来

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是 Android 12 SystemUI 中手势的相关代码: 1. 在 `PhoneWindowManager.java` 文件中添加以下方法: ``` private void handleThreeFingerGesture() { mHasThreeFingerGesture = true; if (mScreenshotChordEnabled && !mScreenOnFully && !mWindowManagerFuncs.isKeyguardLocked()) { if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) { // If the volume down button was already triggered, capture the screen now. mVolumeDownKeyTriggered = false; mPowerManagerWrapper.goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_GESTURE, 0); takeScreenshot(true, true); } else { mVolumeDownKeyTriggered = true; mVolumeDownKeyTime = SystemClock.uptimeMillis(); mVolumeDownKeyConsumedByGestures = true; } } } ``` 2. 在 `PhoneWindowManager.java` 文件的 `interceptMotionBeforeQueueingNonInteractive()` 方法中添加以下代码: ``` case MotionEvent.ACTION_POINTER_DOWN: { final int pointerCount = motionEvent.getPointerCount(); if (pointerCount == 3) { handleThreeFingerGesture(); } break; } ``` 3. 在 `ScreenshotHelper.java` 文件中添加以下方法: ``` public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) { takeScreenshot(finisher, statusBarVisible, navBarVisible, false, true); } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast) { // Call the takeScreenshot method with the necessary parameters. takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, null, true); } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast, Rect crop, boolean nonInteractive) { // Call the appropriate method based on the value of nonInteractive parameter. if (nonInteractive) { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop); } else { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, false /* screenSecure */); } } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast, Rect crop, boolean screenSecure) { // Call the takeScreenshot method with the necessary parameters. takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, true); } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast, Rect crop, boolean screenSecure, boolean runnableFinisher) { // Call the appropriate method based on the value of runnableFinisher parameter. if (runnableFinisher) { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, true /* sensorShade */); } else { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, false /* sensorShade */); } } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast, Rect crop, boolean screenSecure, boolean sensorShade) { // Call the appropriate method based on the value of sensorShade parameter. if (sensorShade) { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, true /* useSystemService */); } else { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, false /* useSystemService */); } } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast, Rect crop, boolean screenSecure, boolean useSystemService) { // Call the takeScreenshot method with the necessary parameters. takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, useSystemService, true /* showFlash */); } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast, Rect crop, boolean screenSecure, boolean useSystemService, boolean showFlash) { // Call the appropriate method based on the value of useSystemService parameter. if (useSystemService) { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, showFlash, true /* useSecureFlag */); } else { takeScreenshot(finisher, statusBarVisible, navBarVisible, isPartial, showToast, crop, screenSecure, showFlash, false /* useSecureFlag */); } } public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible, boolean isPartial, boolean showToast, Rect crop, boolean screenSecure, boolean showFlash, boolean useSecureFlag) { // Get the DisplayManager instance and call the appropriate method based on the value of isPartial parameter. final DisplayManager displayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); if (displayManager == null) { return; } if (isPartial) { // Capture a partial screenshot. capturePartialScreenshot(statusBarVisible, navBarVisible, finisher, showFlash, useSecureFlag); } else { // Capture a full screenshot. final Display display = mContext.getDisplay(); final int rot = display == null ? Surface.ROTATION_0 : display.getRotation(); final int width = mDisplayMetrics.widthPixels; final int height = mDisplayMetrics.heightPixels; final int minLayer = HwFrameworkFactory.getHwNsdImpl().getMinLayer(); final SurfaceControl sc = SurfaceControl.screenshot(new Rect(), width, height, minLayer, rot); if (sc == null) { if (finisher != null) { finisher.run(); } return; } captureScreenshot(sc, finisher, showToast, showFlash, useSecureFlag, width, height, crop, statusBarVisible, navBarVisible, screenSecure); } } ``` 以上是 Android 12 SystemUI 中手势的相关代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值