You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:33:13