剪贴板API调用在不调用onPermissionRequest()的情况下引发NotAllowedError [英] Clipboard API call throws NotAllowedError without invoking onPermissionRequest()
问题描述
我有一个带有按钮的简单页面,按下该按钮后,它会使用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屋!