Window.Print 在 Android WebView (API 23) 中不工作,但在默认浏览器和 Chrome 中工作

Mal*_*ery 7 android webview

从下面的示例代码在这里工作在两个默认的浏览器“互联网”和“Chrome浏览器”的浏览器上的Galaxy Tab S2罚款。

<!DOCTYPE html>
<html>
<body>

<p>Click the button to print the current page.</p>

<button onclick="myFunction()">Print this page</button>

<script>
function myFunction() {
    window.print();
}
</script>

</body>
</html>
Run Code Online (Sandbox Code Playgroud)

但是,当托管在 WebView 中时,单击“打印此页面”时没有任何反应

我的观点 XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.company.MainActivity"
    tools:showIn="@layout/activity_main">

    <WebView
        android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)

MainActivity.Java 具有以下内容:

@Override
protected void onCreate(Bundle savedInstanceState) {
    WebViewClient mWebClient = new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            view.loadUrl(url);
            return true;
        }
    };
    WebView myWebView = (WebView) findViewById(R.id.webview);
    myWebView.setWebViewClient(mWebClient);
    WebSettings webSettings = myWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setGeolocationEnabled(true);
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
    myWebView.loadUrl("https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_print");
}
Run Code Online (Sandbox Code Playgroud)

此处的 WebView 开发人员文档明确指出:

您不能在 HTML 文档中使用 JavaScript 来触发打印。

如何托管网页并允许 JavaScript 打印工作。

我已经想到但还没有找到实现方法的替代方案:

  • 拦截按钮点击,如果点击打印按钮触发我自己的打印代码
  • 用其他一些代码动态替换“打印”按钮 HTML,这样我就可以在我的应用程序中处理它

到目前为止,为了解决这个限制,我已经在我的应用程序中添加了“打印”按钮并运行我自己的打印代码。它工作正常,但会混淆用户体验,因为网页中的“打印”按钮没有任何作用。

MrV*_*lev 2

也许这会回答您的问题: https://bugs.chromium.org/p/chromium/issues/detail ?id=322303

这是 Android WebView 团队的答案:

你好,

我们(Android WebView 团队)计划将此 API 移植到 Android Q(通过支持库也可以使用较低版本,但待定)。我们想了解它可能的用例。

API 将是一个阻塞回调,因为我们想要冻结 DOM/布局树以进行打印渲染,这与 Chrome 的行为相同。

一旦我们有了回调,我们就可以想象得到一个 |PrintDocumentAdapter| 来自回调中的 WebView#getPrintDocumentAdapter(),应用程序可以 1) 使用 |PrintDocumentAdapter| 使用|打印管理器| 让用户选择打印设置或 2) 使用它直接生成 PDF 文件。我们可能希望在调用 PrintDocumentAdapter#onFinish() 时解除阻塞。

此回调仅适用于加载内容时您无法控制 WebView,但应用程序仍需要支持打印功能的情况。否则应用程序可以使用 |PrintDocumentAdapter| 直接地。

我们还想知道您认为 iframe 中的 window.print() (仅打印该 iframe 中的内容)对您是否重要。对此的支持是暂时的,因为 getPrintDocumentAdapter() 没有明显的方法来知道当前的 window.print() 是来自主框架还是 iframe。

有疑问、想法吗?请您反馈一下,谢谢!