webview_flutter - 无法通过 Javascript navigator.clipboard.writeText 复制文本

问题描述 投票:0回答:1

在 Android 上运行此代码示例

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {

    return const MaterialApp(
      home: SafeArea(
        child: WebView(
          initialUrl: "https://www.w3schools.com/howto/howto_js_copy_clipboard.asp",
          javascriptMode: JavascriptMode.unrestricted,
        ),
      ),
    );
  }
}

单击“复制文本”按钮

预期结果: 文本应复制到剪贴板。

实际结果: 日志消息:[INFO:CONSOLE(0)]“未捕获(承诺)NotAllowedError:写入权限被拒绝。”

仅供参考:

我们已经从互联网和人工智能中尝试了很多实验来解决这个问题,但到目前为止都没有奏效,也没有涉及编辑java代码,这似乎不适用于flutter上下文。例如:

AI 目前也建议这样做,但似乎无法编译 😅

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  WebViewController _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter WebView example'),
      ),
      body: WebView(
        initialUrl: 'https://flutter.dev',
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _controller = webViewController;
          _controller.evaluateJavascript("window.addEventListener('flutterInAppWebViewPlatformReady', function(event) {window.flutter_inappwebview.callHandler('test', 'Text to copy').then(function(result) {console.log(result);});});");
        },
        javascriptChannels: <JavascriptChannel>[
          JavascriptChannel(
              name: 'Clipboard',
              onMessageReceived: (JavascriptMessage message) {
                Clipboard.setData(ClipboardData(text: message.message));
              }),
        ].toSet(),
      ),
    );
  }
}

任何帮助将不胜感激。谢谢!

android flutter dart clipboard flutterwebviewplugin
1个回答
0
投票

以下解决了我们特定网站复制按钮的问题以及我们的具体问题:

// Note: To make the following code testable, we wrapped the Flutter clipboard
// First, setup the channel by calling this setupClipboardChannel function after the flutter web view controller is created

const clipboardChannelName = 'Clipboard';

void setupClipboardChannel(WebViewController webViewController, ClipboardWrapper webViewClipboard) {
    Future<void> setCopyBuffer(JavaScriptMessage message) async => webViewClipboard.setData(message.message);
    unawaited(webViewController.addJavaScriptChannel(clipboardChannelName, onMessageReceived: setCopyBuffer));
}

//Second, we call the following setupCopyLinkButtonListeners function in onPageFinished of the flutter web view NavigationDelegates

const jsToPublishClipboardTextWhenCopyButtonClicked = """
  document.querySelectorAll('whateverSelectorNeededToFindYourCopyButton').forEach(link => {
    const textToPutIntoCopyBuffer = 'whateverConcatenationWithLinkProperties' + 'NeededToGetTheTextYouWantToCopy`;
    link.addEventListener('click', () => {
      Clipboard.postMessage(textToPutIntoCopyBuffer);
    });
  });
  """;

Future<void> setupCopyLinkButtonListeners(WebViewController webViewController) async =>
    webViewController.runJavaScript(jsToPublishClipboardTextWhenCopyButtonClicked);

// Then, we saw that every time the user clicked the copy button on our website, the text was actually copied to the clipboard.

仅供参考:这不是所有剪贴板工作的通用修复程序(例如,网站 js 中对“navigator.clipboard.writeText”的所有调用)。但仅当上面的 js 选择器针对特定的复制按钮时才有效。

© www.soinside.com 2019 - 2024. All rights reserved.