安卓使用webView一键截长图宽图
项目中webView要截图,但是不同手机又不能满足截图需要,
增加一个 “截图” 功能! 可以截取 超出屏幕的长图和宽图
效果图

- honor 6x的横屏的下不支持截长图 (原表格内容是可上下左右滑动的)
- 点击上图"一键截图" 截到的图
- 截图后分享到微信(以上贴图是压缩后的效果,原图是比较清晰的)
WebActivity
...
var webSettings = webView!!.settings
webSettings.userAgentString = WebUI.UA
webSettings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
webSettings.javaScriptEnabled = true
webSettings.domStorageEnabled = true
webSettings.builtInZoomControls = true
webSettings.setSupportZoom(true)
webSettings.loadWithOverviewMode = true
webSettings.displayZoomControls = false;
webView.setOnLongClickListener { true }
webView!!.webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
...
}
override fun onJsAlert(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
result?.confirm()
return true
}
override fun onJsPrompt(webView: WebView, url1: String, message: String, defaultValue: String, result: JsPromptResult): Boolean {
"capture" -> {
//从接收到webview的宽高参数
var width = obj.getString("width").toFloat()
var height = obj.getString("height").toFloat()
captureWholePage(SysUtil.px2dp(this@WebUI, width),SysUtil.px2dp(this@WebUI, height))
}
}
}
/**
* 截图
*/
private fun captureWholePage(width: Int, height: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
var bitmap = captureWebViewLollipop(webView, width, height)
//4.4的截图方法测试过,高版本也可以使用但是已经被标为废弃不推荐了
//var bitmap = captureWebViewKitKat(webView)
if (bitmap != null) {
shareCapture(bitmap)
} else {
SmartToast.showInCenter("生成图片出错")
}
} catch (oom: OutOfMemoryError) {
SmartToast.showInCenter("OutOfMemoryError")
}
} else {
SmartToast.showInCenter("当前手机版本过低,不支持截图功能")
}
}
/**
* 5.0以上截长图
*/
private fun captureWebViewLollipop(webView: WebView, height: Int): Bitmap {
webView.measure(View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
webView.layout(0, 0, webView.measuredWidth, height)
webView.isDrawingCacheEnabled = true;
webView.buildDrawingCache()
var longImage = Bitmap.createBitmap(webView.measuredWidth, webView.measuredHeight, Bitmap.Config.ARGB_8888)
var canvas = Canvas(longImage)
webView.draw(canvas)
return longImage
}
/**
* 截图 4.4
*/
private fun captureWebViewKitKat(webView: WebView): Bitmap? {
//获取Picture对象
var picture = webView.capturePicture()
//得到图片的宽和高(没有reflect图片内容)
var width = picture.width
var height = picture.height
if (width > 0 && height > 0) {
//创建位图
var bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
var canvas = Canvas(bitmap)
//绘制(会调用native方法,完成图形绘制)
picture.draw(canvas)
return bitmap
}
return null
}
/**
* 分享到微信,使用第三方shareSDk
*/
private fun shareCapture(bitmap: Bitmap) {
var uri = Uri.parse(MediaStore.Images.Media.insertImage(contentResolver, bitmap, null, null));
val imgPath= getRealFilePath(this,uri)
// 系统的分享到微信会压缩导致查看图片不能显示"查看原图"
// var intent = Intent(Intent.ACTION_SEND)
// intent.type = "image/jpeg"
// intent.putExtra(Intent.EXTRA_STREAM, uri)
// startActivity(Intent.createChooser(intent, "分享"));
var oks = OnekeyShare();
oks.disableSSOWhenAuthorize();
oks.setImagePath(imgPath)
oks.show(this)
}
/**
* 根据Uri获取真实图片路径
*
*
* 一个android文件的Uri地址一般如下:
* content://media/external/images/media/62026
*
* @param context
* @param uri
* @return
*/
fun getRealFilePath(context: Context, uri: Uri?): String? {
if (null == uri) return null
val scheme = uri!!.scheme
var data: String? = null
if (scheme == null)
data = uri!!.path
else if (ContentResolver.SCHEME_FILE == scheme) {
data = uri!!.path
} else if (ContentResolver.SCHEME_CONTENT == scheme) {
val cursor = context.contentResolver.query(uri, arrayOf(MediaStore.Images.ImageColumns.DATA), null, null, null)
if (null != cursor) {
if (cursor!!.moveToFirst()) {
val index = cursor!!.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
if (index > -1) {
data = cursor!!.getString(index)
}
}
cursor!!.close()
}
}
return data
}
Web页面
默认加载的
meta
增加一个方法改造成获取
initial-scale
<script>
;(function () {
//这里页面内容的宽度为960px
var scale = (screen.width / 960).toFixed(2);
document.write('<meta name="viewport" content="width=device-width, initial-scale=' + scale + ', maximum-scale=1, user-scalable=no>')
})();
</script>
- 根据自己页面内容的宽度调整被除数, 截图出来的宽度就是占满的