Android 8.0 截屏

/** * 快照工具 */public class SnapShotUtil {    /**     * 获取屏幕截图。     */    public static Bitmap getScreen(Activity activity) {        View view = activity.getWindow().getDecorView();        //启用绘制缓存        view.setDrawingCacheEnabled(true);        //构建缓存视图        view.buildDrawingCache();        //获得视图的缓存图像        Bitmap cache = view.getDrawingCache();        //状态栏区只有背景色,却截取不到任何文字,因此要手动裁剪掉        Rect activityRect = new Rect();        //获取当前activity的可见区域        view.getWindowVisibleDisplayFrame(activityRect);        Bitmap bitmap = BitmapUtil.crop(cache, activityRect);        //关闭视图缓存机制        view.setDrawingCacheEnabled(false);        //删除视图缓存        view.destroyDrawingCache();        return bitmap;    }    /**     * 通过系统录屏截图     */    public static void getScreenProjection(FragmentActivity activity, Callback callback) {        //调用系统服务,会弹出一个是否允许录屏的对话框        MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);        Intent intent = mediaProjectionManager.createScreenCaptureIntent();        ActivityLauncher.init(activity).startActivityForResult(intent, (resultCode, data) -> {            MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);            //返回null,说明用户拒绝            if (mediaProjection == null) {                return;            }            Point screenSize = DisplayUtil.getResolution(activity);            /*            The producer output buffer format 0x1 doesn't match the ImageReader's configured buffer format 0x4.            所以各式只能用8888,不能用565             */            ImageReader imageReader = ImageReader.newInstance(screenSize.x, screenSize.y, PixelFormat.RGBA_8888, 1);            int densityDpi = DisplayUtil.getDensityDpi(activity);            VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay("screen-mirror",                    screenSize.x,                    screenSize.y,                    densityDpi,                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,                    imageReader.getSurface(),                    null,                    //传null表示在回调在主线程中执行                    null);            //在获取Image的时候,得先暂停1秒左右,不然就会获取失败(原因未知)            SystemClock.sleep(1000);            Image image = imageReader.acquireLatestImage();            Bitmap bitmap = BitmapUtil.fromImage(image);            image.close();            callback.invoke(bitmap);            virtualDisplay.release();        });    }    /*     Android 在5.0 之后支持了实时录屏的功能。     通过实时录屏我们可以拿到截屏的图像。     同时可以通过在Service中处理实现后台的录屏。     */    @RequiresApi(Build.VERSION_CODES.O)    public static void getViewBySystem(Activity activity, View view, Callback callback) {        int width = view.getWidth();        int height = view.getHeight();        //这里只能用8888,不能用其它的,否则一片黑取不到图像        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888, true);        Window window = activity.getWindow();        final int[] location = new int[2];        view.getLocationInWindow(location);        Rect rect = new Rect(location[0], location[1], location[0] + view.getWidth(), location[1] + view.getHeight());        final Handler handler = new Handler(Looper.getMainLooper());        PixelCopy.request(window, rect, bitmap, copyResult -> {            callback.invoke(copyResult == PixelCopy.SUCCESS ? bitmap : null);        }, handler);    }    /**     * 截取视图     */    public static Bitmap getView(View view) {        view.setDrawingCacheEnabled(true);        view.buildDrawingCache();        Bitmap cache = view.getDrawingCache();        Bitmap bitmap = BitmapUtil.clone(cache);        view.setDrawingCacheEnabled(false);        view.destroyDrawingCache();        return bitmap;    }    /**     * 截取 ScrollView 视图     */    public static Bitmap getRecyclerView(RecyclerView recyclerView, int maxSize) {        RecyclerView.Adapter adapter = recyclerView.getAdapter();        int height = 0;        //取列表项和缓存项中的最小值        int size = Math.min(maxSize, adapter.getItemCount());        //把每个item的绘图缓存存储在LruCache中        LruCache bitmapCache = new LruCache<>(maxSize);        for (int i = 0; i < size; i++) {            //手动调用创建和绑定ViewHolder方法,            RecyclerView.ViewHolder holder = adapter.createViewHolder(recyclerView, adapter.getItemViewType(i));            adapter.onBindViewHolder(holder, i);            /*            测量            MeasureSpec.EXACTLY - 视图应该是这么多像素,无论它实际上有多大。            MeasureSpec.AT_MOST - 如果视图的尺寸较小,则视图可以是此尺寸或更小。            MeasureSpec.UNSPECIFIED - 视图可以是它需要的任何大小,以显示它需要显示的内容。             */            holder.itemView.measure(                    View.MeasureSpec.makeMeasureSpec(recyclerView.getWidth(), View.MeasureSpec.EXACTLY),                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));            //布局            holder.itemView.layout(0, 0,                    holder.itemView.getMeasuredWidth(),                    holder.itemView.getMeasuredHeight());            //开启视图绘制缓存            holder.itemView.setDrawingCacheEnabled(true);            holder.itemView.buildDrawingCache();            Bitmap drawingCache = holder.itemView.getDrawingCache();            Bitmap cacheClone = BitmapUtil.clone(drawingCache);            if (cacheClone != null) {                bitmapCache.put(i, cacheClone);            }            //禁用视图绘制缓存            holder.itemView.setDrawingCacheEnabled(false);            //销毁视图绘制缓存            holder.itemView.destroyDrawingCache();            //获取itemView的实际高度并累加//            height += holder.itemView.getMeasuredHeight();            height += cacheClone.getHeight();        }        //这里只能用8888,不能用其它的,否则一片黑取不到图像        Bitmap dstBitmap = Bitmap.createBitmap(recyclerView.getWidth(), height, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(dstBitmap);        Paint paint = new Paint();        for (int i = 0, top = 0; i < size; i++) {            Bitmap bitmap = bitmapCache.get(i);            canvas.drawBitmap(bitmap, 0, top, paint);            top += bitmap.getHeight();        }        return dstBitmap;    }    /**     * 截取 ScrollView 视图     */    public static Bitmap getScrollView(ScrollView scrollView) {        int height = 0;        //ScrollView理论上只有一个子View        for (int i = 0; i < scrollView.getChildCount(); i++) {            height += scrollView.getChildAt(i).getHeight();        }        //这里只能用8888,不能用其它的,否则一片黑取不到图像        Bitmap bitmap = Bitmap.createBitmap(scrollView.getWidth(), height, Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(bitmap);        scrollView.draw(canvas);        return bitmap;    }}
public interface Callback {    void invoke() {}}

更多相关文章

  1. android 从webview中读取缓存的图片
  2. android对大图片的缓存处理
  3. android image cache 图片缓存 异步 下载
  4. 简析Android中LruCache缓存类
  5. Android中如何实现图像的闪动
  6. Android Studio 无法预览xml布局视图
  7. android如何让webview里的资源访问本地缓存
  8. Android 中的图形图像的渲染
  9. Android视图绘画与属性动画

随机推荐

  1. Android实现底部弹出按钮菜单升级版
  2. Iphone,Imac,Win7,Android的日历同步
  3. Windows环境下 android-ndk-r10c 环境搭
  4. 转载:Android(安卓)service 实现过程
  5. android使用自定义属性
  6. android批量插入数据效率对比
  7. Android五大布局(二)——RelativeLayout、T
  8. Android日常知识收集与总结之Android的Di
  9. android EditView ime
  10. build android adb on debian sid amd64