剪贴板API调用在不调用onPermissionRequest()的情况下引发NotAllowedError [英] Clipboard API call throws NotAllowedError without invoking onPermissionRequest()

查看:319
本文介绍了剪贴板API调用在不调用onPermissionRequest()的情况下引发NotAllowedError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有按钮的简单页面,按下该按钮后,它会使用Async Clipboard API写入剪贴板.

I have a simple page with a button, that when pressed, uses the Async Clipboard API to write to the clipboard.

<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上,它将引发以下错误:

This works on both Chrome and Firefox, desktop and mobile. However on Android Webview it throws the following error:

NotAllowError: Write permission denied.

我认为我需要重写WebChromeClient.onPermissionRequest()来授予权限,但是奇怪的是onPermissionRequest()似乎没有被调用,并且仍然抛出相同的错误.

I figured I need to override WebChromeClient.onPermissionRequest() to grant the permission, but strangely onPermissionRequest() does not seem to have been invoked, and the same error is still thrown.

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());
}

我仍然遇到相同的错误:

I still get the same error:

NotAllowError: Write permission denied.

Logcat也什么也没记录.

Also Logcat logged nothing.

我怀疑我的Android应用程序可能需要其他权限才能访问剪贴板,但根据 https://developer.android.com/about/versions/10/privacy/changes#clipboard-data ,当我的应用具有焦点时,它应该具有权限.实际上,以下代码有效:

I suspected maybe my Android App requires additional permissions to access the clipboard, but according to https://developer.android.com/about/versions/10/privacy/changes#clipboard-data, my App should have permission when it has focus. Indeed, the following code works:

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

在请求权限的操作需要权限的情况下,我还在AndroidManifest.xml中声明了以下内容:

I also declared the following in AndroidManifest.xml in case the action of requesting permission requires permission:

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

这什么也没做.

因此,获得应用级许可可能不是问题.

So it is probably not an issue with App level permission.

发生了什么事?

如何获取异步剪贴板API调用以在Webview中工作?

How can I get Async Clipboard API calls to work in Webview?

操作系统:Android 10 Q

OS: Android 10 Q

Webview:v.81.0.4044.111

Webview: v. 81.0.4044.111

推荐答案

剪贴板API的writeText方法文档说,我们需要使用Permissions API获得clipboard-write许可,但是在WebView中未定义navigator.permission,也许是因为它们没有不想将网络权限与Android操作系统权限混为一谈.

Clipboard API's writeText method docs says, we need to obtain clipboard-write permission using Permissions API but navigator.permission is undefined in WebView, maybe because they don't want to mix web permissions with Android OS permissions.

还有另一种方法可以从Android WebView复制文本到剪贴板:通过从WebView JavaScript(JS)代码调用本机Java方法.

There is one more way by which we can copy text to clipboard from Android WebView: by calling native Java method from WebView JavaScript (JS) code.

在WebView中启用JS:

Enable JS in WebView:

myWebView.getSettings().setJavaScriptEnabled(true);

添加JS接口:

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

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

Create a method to copy the text to clipboard using 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调用上述方法:

Then call the above method using testClipboard:

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

这篇关于剪贴板API调用在不调用onPermissionRequest()的情况下引发NotAllowedError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆