Android 截屏
2022-08-09 本文已影响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);
}
}
}