Android5.0 以上 Android 12 一下系统截屏调用

1.使用方式

Android 5.0以上12 以下使用一下方式截图,以下是通过反射调用系统默认截图实现
前提应用需要有系统权限
转换成bitmap 后保存到本地 如果需要矩形截图的 需要在图片基础上进行矩形裁剪

package com.igrs.screencapture;

import android.accessibilityservice.AccessibilityService;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorSpace;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Build;
import android.os.FileObserver;
import android.os.Handler;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;


import androidx.annotation.NonNull;

import com.droidlogic.app.ScreenControlManager;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author markLiu
 * @title ViewUtil
 * @time 2021/10/28 9:53
 * @description
 **/
public class ScreenCaptureService {

    public static String cachePath;

    public static int dp2px(Context context, float dp) {
        return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f);
    }

    public static Bitmap screenShot(int x, int y,Context context) {
        Class<?> cls = null;
        Bitmap bitmap = null;
        try {
            cls = Class.forName("android.view.SurfaceControl");
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if (Build.VERSION.SDK_INT <= 28) {
             // android 8.0
                Method method = cls.getMethod("screenshot", int.class, int.class);
                Object obj = method.invoke(null, x, y);
                bitmap = (Bitmap) obj;
            } else if (Build.VERSION.SDK_INT <= 30) {
            //android 12 
                Method method = cls.getMethod("screenshot", Rect.class, int.class, int.class, int.class);
                Object obj = method.invoke(null, new Rect(0, 0, x, y), x, y, 0);
                bitmap = (Bitmap) obj;
            } else {
            	// andoird 12以上调用方式
                bitmap = ScreenshotUtil.captureScreenshot(context,new   Rect(0, 0, x, y))      ;
            }
        }catch (Exception e){

        }
        return bitmap;
    }

    public static void measureView(View view) {
        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    }

    public static boolean isAppInstalled(Context context, String packageName) {
        try {
            context.getPackageManager().getPackageInfo(packageName, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }
    public static Bitmap savecreen(String name,Context context) {
        File cacheDir = context.getCacheDir();
        Log.i("liuhongliang","cacheDir" +cacheDir.toString());
        cachePath = "/sdcard/" + name + ".png";
        String cmd = "screencap -p /sdcard/" + name + ".png";
        try {
            // 权限设置
            Process p = Runtime.getRuntime().exec("sh");
            // 获取输出流
            OutputStream outputStream = p.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(
                    outputStream);
            // 将命令写入
            dataOutputStream.writeBytes(cmd);
            // 提交命令
            dataOutputStream.flush();
            // 关闭流操作
            dataOutputStream.close();
            outputStream.close();
        } catch (Throwable t) {
            t.printStackTrace();
        }

        return  null;
    }
    /**
     *
     * @param path 图片路径
     * @return
     */
    /**
     * 将本地图片转成Bitmap
     * @param path 已有图片的路径
     * @return
     */
    public static Bitmap openImage(String path){

        Bitmap bitmap = null;
        File file = new File(path);
        if (!file.exists()){
            Log.i("liuhongliang","不存在");
        }
        try {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
            bitmap = BitmapFactory.decodeStream(bis);
            bis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

}

Android13 截屏适配截屏

1.需要Android 13 内部源码有改动,无法通过反射直接 screenShot调用截屏
需要将Android 13 源码jar 包fromwork 导入进来

以下代码是需要从源码中提取出来

package com.igrs.screencapture;

import static android.view.Display.DEFAULT_DISPLAY;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.IBinder;
import android.util.Log;
import android.view.Display;
import android.view.DisplayAddress;
import android.view.SurfaceControl;

public class ScreenshotUtil {
	// 直接调用
    public static Bitmap captureScreenshot(Context context, Rect crop) {
        int width = crop.width();
        int height = crop.height();
        Bitmap screenshot = null;
        final Display display = getDefaultDisplay(context);
        final DisplayAddress address = display.getAddress();
        if (!(address instanceof DisplayAddress.Physical)) {
            Log.e("####", "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;
    }

    public static Display getDefaultDisplay(Context context) {
        DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
        return displayManager.getDisplay(DEFAULT_DISPLAY);
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值