实现Android 版网页快照功能

现在一般的购物网站,在你完成交易后都会将页面拍照以免日后发生商务纠纷,而对于我们移动开发者这个传统互联网上的优秀经验也同样给了我们一些设计上的启迪,接下来我将几种实现思路写出来供大家参考。

方案一:使用WebViewClient的onPageFinished事件

我们使用WebView当做程序里的内嵌式浏览器的显示网页的时候,如果不进行特殊设置,当用户点击WebView里面的链接就会另外启动Android手机内置的浏览器,而离开当前的Activity,针对这一问题,我们可以进行自定义浏览器的客户端设置,代码如下:

 

  1. mWebView.setWebViewClient(new WebViewClient(){  
  2.   
  3. });  

 

在setWebViewClient()的内容时,我们可以重写onPageFinished()来捕捉WebView加载完毕的事件,关键代码如下:

  1.     /* WebView取得WebSettings */  
  2.     WebSettings webSettings = wView.getSettings();  
  3.     /* 设置能运行JavaScript */  
  4.     webSettings.setJavaScriptEnabled(true);  
  5.       
  6.     /*  */  
  7.     /*  */  
  8.     /* WebView设置WebViewClient */  
  9.     wView.setWebViewClient(new WebViewClient(){  
  10.         @Override  
  11.         public void onPageFinished(WebView view, String url) {  
  12.             /* 获取画面 */  
  13.             Picture picture = view.capturePicture();  
  14.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  15.             /* 获取宽高 */  
  16.             int width = picture.getWidth();  
  17.             int height = picture.getHeight();  
  18.             if (width > 0 && height > 0) {  
  19.     Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);  
  20.     Canvas canvas = new Canvas(bitmap);  
  21.     picture.draw(canvas);  
  22.     bitmap.compress(Bitmap.CompressFormat.JPEG, 90, baos);  
  23.     FileOutputStream fos = null;  
  24.     try {  
  25.         if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {                            
  26.             fos = new FileOutputStream(Environment.getExternalStorageDirectory());  
  27.             if (fos!=null) {  
  28.                 bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);  
  29.                 fos.close();  
  30.                 Toast.makeText(ATestActivity.this, "快照保存成功",Toast.LENGTH_LONG).show();  
  31.             }  
  32.         }  
  33.     } catch (Exception e) {  
  34.         e.printStackTrace();  
  35.     }  
  36. }  
  37.               
  38.             super.onPageFinished(view, url);  
  39.         }  
  40.     });  


方案二:

使用View的 Bitmap  getDrawingCached(boolean autoScale)方法实现,不过要注意的是cache 先要通过setDrawingCacheEnable方法把cache开启,然后再调用getDrawingCache方法就可以获得view的 cache图片了。buildDrawingCache方法可以不用调用,因为调用getDrawingCache方法时,若果 cache没有建立,系统会自动调用buildDrawingCache方法生成cache。若果要更新cache, 必须要调用destoryDrawingCache方法把旧的cache销毁,才能建立新的。
当调用setDrawingCacheEnabled方法设置为false, 系统也会自动把原来的cache销毁。
   ViewGroup在绘制子view时,而外提供了两个方法
   void setChildrenDrawingCacheEnabled(boolean enabled)
   setChildrenDrawnWithCacheEnabled(boolean enabled)
   setChildrenDrawingCacheEnabled方法可以使viewgroup里所有的子view开启cache, setChildrenDrawnWithCacheEnabled使在绘制子view时,若该子view开启了cache, 则使用它的cache进行绘制,从而节省绘制时间。
   获取cache通常会占用一定的内存,所以通常不需要的时候有必要对其进行清理,通过destroyDrawingCache或setDrawingCacheEnabled(false)实现。

 

  1. public static Bitmap convertViewToBitmap(View view){  
  2.        view.buildDrawingCache();  
  3.     Bitmap bitmap = view.getDrawingCache();  
  4.     return bitmap;   
  5. }  

 

一般情况下,直接使用上面方法是能够正常的工作。但有时候,生成Bitmap会出现问题(Bitmap全黑色)。主要原因是drawingCache的值大于系统给定的值。我们可以看一下buildDrawingCache()方法中的一段代码:

 

  1. if (width <= 0 || height <= 0 ||(width * height * (opaque && !translucentWindow ? 2 : 4) > ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {     
  2.                  destroyDrawingCache();     
  3.                  return;     
  4.   }    

 

上面的代码中,width和height是所要cache的view绘制的宽度和高度,所以(width * height * (opaque && !translucentWindow ? 2 : 4) 计算的是当前所需要的cache大小。 ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize()得到的是系统 所提供的最大的DrawingCache的值。当所需要的drawingCache >系统所提供的最大DrawingCache值时,生成Bitmap就会出现问题,此时获取的Bitmap就为null。

所以在只需要修改所需的cache值就可以解决问题了。代码实现如下:

    1. public static Bitmap convertViewToBitmap(View view){  
    2.       view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));  
    3.         view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());  
    4.         view.buildDrawingCache();  
    5.         Bitmap bitmap = view.getDrawingCache();  
    6.   
    7.      return bitmap;  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。