Android implements screenshot sharing function through WebView

In the development process of an APP project, the function of sharing pictures is often used, and sometimes it is necessary to obtain a specified shared picture according to the current user information, for example, the user name, Uid, user avatar and other information are required to be displayed in the user sharing picture. There are two main implementation methods that come to mind: 
1. Drawing through the Canvas method that comes with the android SDK. 
2. Realize the interaction between the client and H5 through webView, and then take screenshots of the H5 interface. 
This article mainly introduces the implementation process of the second method and the implementation method of the first method. I will explain it in the blog when I have time. Let's start the content of this article. 
First determine the logic we want to implement: 1. The interaction between the client and H5, the client sends user information (username, Uid, user avatar, etc.) to H5; 2. The client intercepts the realization of the WebView function; 3. The sharing function 's addition.

1. The client interacts with H5 
Add the webView layout to the interface layout, and initialize the WebView layout (network permissions are required here, and no separate processing is required)

wv_imgweb = (WebView) findViewById(R.id.h5_wv_imgweb);

WebSettings webSettings = wv_imgweb.getSettings();
//此处可更加具体的H5界面功能进行相应的WebSettings设置,本文只是演示基本效果
        webSettings.setJavaScriptEnabled(true);
        webSettings.setSupportZoom(false); 
        wv_imgweb.requestFocusFromTouch();
        wv_imgweb.setDrawingCacheEnabled(true);
        wv_imgweb.setVerticalScrollBarEnabled(false);
        wv_imgweb.setHorizontalScrollBarEnabled(false);
        wv_imgweb.setVerticalScrollbarOverlay(false);
        wv_imgweb.setHorizontalScrollbarOverlay(false);
        wv_imgweb.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                //加载逻辑的处理
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                //加载逻辑的处理
            }
        });

//添加用户信息参数,加载H5分享地址
wv_imgweb.loadUrl(h5_url);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

2. Implementation of the screenshot function 
After the WebView page above is loaded, you can call the screenshot function and save the picture in the local specified folder (storage permission is required here, no separate processing is required) 
WebView in android can be done in a variety of ways Implement screenshots, the following are different introductions:

  • 2.1 Capture the contents of the screen

    The first way is to capture the content displayed on the screen through Bitmap bitmap = webView.getDrawingCache(). Note that calling this method setDrawingCacheEnabled(true) must be set to true;

  • 2.2 Intercept the entire WebView content

    The second way is to capture the content of the entire WebView through Picture snapShot = wv_imgweb.capturePicture()

Picture snapShot = wv_imgweb.capturePicture();
if (snapShot != null && snapShot.getWidth() > 0 && snapShot.getHeight() > 0) {
      Bitmap bitmap = Bitmap.createBitmap(snapShot.getWidth(), snapShot.getHeight(), Bitmap.Config.ARGB_8888);//设置相应的图片质量
      Canvas canvas = new Canvas(bitmap);
      snapShot.draw(canvas);
//将截取的图片保存到本地
try {
      File appFile = new File(Environment.getExternalStorageDirectory() + "/testpic/app");
      if (!appFile.exists() && !appFile.isDirectory()) {
         appFile.mkdirs();
      }
      String fileName = Environment.getExternalStorageDirectory().getPath() + "/testpic/app/share.jpg";
      FileOutputStream fos = new FileOutputStream(fileName);
      //设置保存本地图片质量
      bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
      fos.close();
      } catch (Exception e) {
          UIUtils.setLogInfo("eee", e.getMessage());
      }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 2.3截取整个WebView内容

    Android 为了提高各方面的绘制速度(如滚动操作),为每一个 View 建立一个缓存,使用 View.buildDrawingCache 为自己的 View 建立相应的缓存, 这个 cache 就是一个 bitmap 对象。利用这个功能可以对整个屏幕视图进行截屏并生成 Bitmap ,也可以获得指定的 View 的 Bitmap 对象。

wv_imgweb.measure(View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        wv_imgweb.layout(0, 0, wv_imgweb.getMeasuredWidth(), wv_imgweb.getMeasuredHeight());
        wv_imgweb.setDrawingCacheEnabled(true);
        wv_imgweb.buildDrawingCache();
        Bitmap longImage = Bitmap.createBitmap(wv_imgweb.getMeasuredWidth(),
                wv_imgweb.getMeasuredHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(longImage);  // 画布的宽高和 WebView 保持一致
        Paint paint = new Paint();
        canvas.drawBitmap(longImage, 0, wv_imgweb.getMeasuredHeight(), paint);
        wv_imgweb.draw(canvas);
        //将截取的图片保存到本地
        try {
            File appFile = new File(Environment.getExternalStorageDirectory() + "/testpic/app");
            if (!appFile.exists() && !appFile.isDirectory()) {
                appFile.mkdirs();
            }
            String fileName = Environment.getExternalStorageDirectory().getPath() + "/testpic/app/share.jpg";
            FileOutputStream fos = new FileOutputStream(fileName);
            longImage.compress(Bitmap.CompressFormat.JPEG, 70, fos);
            fos.close();
        } catch (Exception e) {
            UIUtils.setLogInfo("eee", e.getMessage());
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

问题:在5.0+上会发现,截取的快照只显示了webview中显示出来的那部分,没有显示出来的部分是空白的。通过google找到了原因,在5.0+版本上,Android对webview做了优化,旨在减少内存占用以提高性能。因此在默认情况下会智能的绘制html中需要绘制的部分,其实就是当前屏幕展示的html内容,因此会出现未显示的图像是空白的。解决办法是调用enableSlowWholeDocumentDraw()方法。这个方法需要在webview创建之前调用,在Activity里就是在setContentView前去调用,此方法会有显著的性能开销。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325375117&siteId=291194637