Android Kotlin中WebView内JavaScript打印功能失效问题求助
解决WebView中JavaScript打印无响应的问题
问题说明
以下HTML代码在Android自带浏览器和Chrome中点击按钮可正常触发打印:
<!DOCTYPE html> <p>Click the button to print the current page.</p> <button onclick="myFunction()">Print this page</button> <script> function myFunction() { window.print(); } </script>
但将该网页加载到WebView后,点击"Print this page"按钮无任何反应。根据官方文档,WebView本身不支持通过HTML中的JavaScript触发打印功能。目前临时方案是在APP中添加独立打印按钮,但网页内的按钮无响应会影响用户体验,需要让网页内的打印按钮正常工作。
解决方案:拦截JS的window.print()调用,触发Android原生打印
通过以下步骤实现网页内打印按钮的功能:
1. 定义供JavaScript调用的打印工具类
创建一个带有@JavascriptInterface注解的类,提供触发原生打印的方法:
class PrintInterface(private val webView: WebView) { @JavascriptInterface fun printPage() { val printManager = webView.context.getSystemService(PRINT_SERVICE) as PrintManager val jobName = "${webView.title} 打印" // 创建打印文档适配器 val printAdapter = webView.createPrintDocumentAdapter(jobName) // 配置打印属性 val printAttributes = PrintAttributes.Builder() .setMediaSize(PrintAttributes.MediaSize.ISO_A4) .build() // 启动打印任务 printManager.print(jobName, printAdapter, printAttributes) } }
2. 修改MainActivity,配置WebView并注入JS拦截代码
更新MainActivity的代码,添加JS接口,并在网页加载完成后注入JS代码替换window.print():
import android.os.Bundle import android.print.PrintAttributes import android.print.PrintManager import android.webkit.JavascriptInterface import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private lateinit var webView: WebView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) webView = findViewById(R.id.webview) // 配置WebView基础设置 val webSettings: WebSettings = webView.settings webSettings.javaScriptEnabled = true webSettings.domStorageEnabled = true // 添加JS接口,命名为"AndroidPrint" webView.addJavascriptInterface(PrintInterface(webView), "AndroidPrint") // 设置WebViewClient,在页面加载完成后注入JS代码 webView.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) // 注入JS代码,替换window.print()为调用Android接口的方法 view?.loadUrl("javascript:window.print = function() { AndroidPrint.printPage(); }") } } webView.loadUrl("http://10.10.0.10:3112/") } // 打印工具类 class PrintInterface(private val webView: WebView) { @JavascriptInterface fun printPage() { val printManager = webView.context.getSystemService(PRINT_SERVICE) as PrintManager val jobName = "${webView.title} 打印" val printAdapter = webView.createPrintDocumentAdapter(jobName) val printAttributes = PrintAttributes.Builder() .setMediaSize(PrintAttributes.MediaSize.ISO_A4) .build() printManager.print(jobName, printAdapter, printAttributes) } } }
3. 权限说明
确保AndroidManifest.xml中已添加必要的网络权限(你已配置),打印功能无需额外权限,ACCESS_PRINT_JOB_SERVICE可移除,该权限用于访问打印任务服务,当前场景不需要。
原理说明
- 通过
addJavascriptInterface将Android的打印方法暴露给JavaScript,命名为AndroidPrint - 在网页加载完成后,注入JS代码覆盖原生的
window.print()函数,使其调用Android提供的printPage()方法 - 当网页内的按钮触发
window.print()时,实际会调用Android的原生打印逻辑,从而实现打印功能
内容的提问来源于stack exchange,提问作者hadi
相关产品推荐
相关产品推荐

