美文网首页
Android 截屏

Android 截屏

作者: 红鲤鱼与绿鲤鱼与驴与鱼 | 来源:发表于2022-08-09 10:33 被阅读0次

最近做了一个截屏的功能,需要每个页面在跳转的时候截屏然后上传到后台,后台管理系统上就可以看到用户当前在哪个页面
截屏的时候遇到了两种情况 一个是页面还没渲染完,另一种是页面渲染完了

  • 1、如果是页面已经渲染完了(只是布局UI加载完,并不是指网络请求的数据也加载完),我们直接截屏是没有问题的,因为我们需要拿到 DecorView 布局加载到Activity上时 DecorView 是可以拿到宽高的
    // 开始截屏
    public static void screenshotView(Activity activity) {
        WeakReference<Activity> activityWeakReference = new WeakReference<>(activity);
        //获取到DecorView
        View view = activityWeakReference.get().getWindow().getDecorView();
        LogUtil.e("height:" + view.getHeight() + "  width:" + view.getWidth());
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_4444);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
        view.setDrawingCacheEnabled(false); // 清空缓存,可用于实时截图
    }
  • 2 、如果页面还没有加载出来怎么办,拿到的 DecorView 宽高是0,就会导致Bitmap是null,这时候我们需要监听一下页面布局的变化,通过 view.getViewTreeObserver().addOnGlobalLayoutListener();
    下面是完整的代码:
public class ScreenUtils {
    private static final String TAG = "ScreenUtils";

    private static MyListener myListener;

    // 开始截屏
    public static void screenshotView(Activity activity) {
        WeakReference<Activity> activityWeakReference = new WeakReference<>(activity);

        View view = activityWeakReference.get().getWindow().getDecorView();
        LogUtil.e("height:" + view.getHeight() + "  width:" + view.getWidth());
        if (view.getHeight() > 0 && view.getHeight() > 0) {
            LogUtil.e("直接上传");
            captureScreen(view);
        } else {
            LogUtil.e("观察变化上传");
            myListener = new MyListener(view);
            view.getViewTreeObserver().addOnGlobalLayoutListener(myListener);
        }
    }

    //将Bitmap保存成图片到本地
    public static void saveBitmapToJPG(Bitmap bitmap, File file) throws IOException {
        Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(newBitmap);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(bitmap, 0, 0, null);
        OutputStream stream = new FileOutputStream(file);
        //压缩图片
        newBitmap.compress(Bitmap.CompressFormat.JPEG, 10, stream);
        stream.close();
    }

    //截屏
    private static void captureScreen(View view) {
        Log.e(TAG, "高:" + view.getHeight());
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_4444);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
        view.setDrawingCacheEnabled(false); // 清空缓存,可用于实时截图
        if (bitmap == null) {
            Log.e(TAG, "screenshotView: 截屏失败");
        } else {
            Log.e(TAG, "screenshotView: 截屏成功");
        }
        //获取到本地存储路径
        File file = new File(FileUtils.getFileStorageRootPath() + "/screen.jpeg");

        Observable.create((ObservableOnSubscribe<File>) emitter -> {
                    try {
                        saveBitmapToJPG(bitmap, file);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    //发射
                    emitter.onNext(file);
                    emitter.onComplete();
                }).subscribeOn(Schedulers.newThread())
                .observeOn(Schedulers.io())
                .subscribe(new Observer<File>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(File file) {
                        Log.e(TAG, "onNext: " + file.getAbsolutePath());
                        //在此上传图片到服务器
                    }

                    @Override
                    public void onError(Throwable e) {
                        LogUtil.e("报错:" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        LogUtil.e("完成");
                    }
                });
    }

    static class MyListener implements ViewTreeObserver.OnGlobalLayoutListener {
        private final View view;

        public MyListener(View view) {
            this.view = view;
        }

        @Override
        public void onGlobalLayout() {
            view.getViewTreeObserver().removeOnGlobalLayoutListener(myListener);
            captureScreen(view);
        }
    }
}

相关文章

  • android 截屏实现

    Android 截屏分为四种:View 截屏、WebView 截屏、系统截屏 和 adb 截屏 1、View 截屏...

  • Android 截屏方式整理

    Android 实现截屏方式整理 可能的需求: 截自己的屏 截所有的屏 带导航栏截屏 不带导航栏截屏 截屏并编辑选...

  • 安卓截图笔记

    Android截屏 Android截屏的原理:获取具体需要截屏的区域的Bitmap,然后绘制在画布上,保存为图片后...

  • Android截屏方案

    Android截屏 Android截屏的原理:获取具体需要截屏的区域的Bitmap,然后绘制在画布上,保存为图片后...

  • 基于MediaProjection实现Android移动手机截屏

    Android软件应用经常要求实现截屏和录屏的功能,那么如何实现Android软件截屏和录屏功能呢?本文将介绍基于...

  • ScreenShotUtils--Android实现截屏并保存在

    添加权限(AndroidManifest.xml文件里) 实现截屏(Java代码) 转自Android实现截屏并保...

  • Android之防截屏

    Android防截屏是防止泄密的措施之一,防截屏的措施有两种,一种是禁止截屏,另一种是监听用户是否截屏,这样就知道...

  • Android截屏

    1、android 5.0开始加入了MediaProjection,通过MediaProjection我们可以快速...

  • android 截屏

  • Android 截屏

    1.截屏 Android的View类中提供了获取控件绘制缓存的方法,这种截屏的方式仅限于应用内自己的Activit...

网友评论

      本文标题:Android 截屏

      本文链接:https://www.haomeiwen.com/subject/xngowrtx.html