在没有调用onPermissionRequest()的情况下,剪贴板API调用会引发NotAllowedError。

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

我有一个简单的页面,上面有一个按钮,当按下这个按钮时,会使用Async Clipboard API来写入剪贴板。

<body>
  <button type="button" onclick="testClipboard();">
    Test Clipboard
  </button>
</body>
function testClipboard() {
  navigator.clipboard.writeText("Clipboard API Test").then(
    v => alert("Success"),
    e => alert("Fail\n" + e));
}

这在Chrome和Firefox、桌面和移动设备上都能工作。然而在Android Webview上,它却抛出了以下错误。

NotAllowError: Write permission denied.


我想我需要覆盖 WebChromeClient.onPermissionRequest() 但奇怪的是 onPermissionRequest() 似乎并没有被调用,仍然出现同样的错误。

public class WebChromeController extends WebChromeClient {
  @Override
  public void onPermissionRequest(PermissionRequest request) {
    Log.d("myTag", "Permission request");
    Log.d("myTag", request.getResources().toString());
    request.grant(request.getResources());
  }
}
protected void initWebView() {
  // ...
  myWebView.setWebChromeClient(new WebChromeController());
}

我仍然得到同样的错误。

NotAllowError: Write permission denied.

Logcat也没有任何记录


我怀疑可能我的Android App需要额外的权限才能访问剪贴板,但根据 https:/developer.android.comaboutversions10privacychanges#clipboard-data。,我的App在有焦点的时候应该有权限。事实上,下面的代码是可行的。

ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("MyLbl", "I have permission");
clipboard.setPrimaryClip(clip);

我还在下面声明了 AndroidManifest.xml 以防请求许可的行动需要许可。

<uses-permission android:name="android.webkit.PermissionRequest" />

这没有任何作用.

所以这可能不是App级权限的问题。


到底发生了什么?

如何让Async Clipboard API调用在Webview中工作?


操作系统:Android 10 Q

Webview: v. 81.0.4044.111

javascript android android-webview clipboard
1个回答
4
投票

剪贴板API writeText 方法文档中说,我们需要获得 clipboard-write 使用Permissions api的权限,但 navigator.permission 在webview中是未定义的,也许是因为他们不想把web权限和android操作系统的权限混在一起。

还有一种方法,我们可以从android webview中复制文本到剪贴板(通过从webview的javascript代码中调用本地java方法)。

首先在webview上启用javascript。

myWebView.getSettings().setJavaScriptEnabled(true);

然后添加javascript接口。

myWebView.addJavascriptInterface(new WebAppInterface(), "NativeAndroid");

创建一个方法,将文本复制到剪贴板,使用的是 android.content.ClipboardManager

public class WebAppInterface {
    @JavascriptInterface
    public void copyToClipboard(String text) {
        ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText("demo", text);
        clipboard.setPrimaryClip(clip);
    }
}

现在你可以从 testClipboard 方法。

function testClipboard() {
  navigator.clipboard.writeText("Clipboard API Test").then(
    v => alert("Success"),
    e => alert("Fail\n" + e));

  NativeAndroid.copyToClipboard("Clipboard API Test");
}
© www.soinside.com 2019 - 2024. All rights reserved.