剪贴板 API 调用在未调用 onPermissionRequest() 的情况下抛出 NotAllowedError
Clipboard API call throws NotAllowedError without invoking onPermissionRequest()
我有一个带有按钮的简单页面,当按下按钮时,使用异步剪贴板 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 应用程序可能需要额外的权限才能访问剪贴板,但根据 https://developer.android.com/about/versions/10/privacy/changes#clipboard-data,我的应用程序在获得焦点时应该有权限。实际上,以下代码有效:
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" />
这没有任何作用。
所以这可能不是应用级别权限的问题。
发生了什么事?
如何让异步剪贴板 API 调用在 Webview 中工作?
OS: Android 10 Q
网络视图:v. 81.0.4044.111
剪贴板 API 的 writeText
方法文档说,我们需要使用权限 API 获得 clipboard-write
权限,但 navigator.permission
在 WebView 中未定义,可能是因为他们不想将 Web 权限与 Android OS 权限混合使用。
还有一种方法可以将文本从 Android WebView 复制到剪贴板:通过从 WebView JavaScript (JS) 代码调用本机 Java 方法。
在 WebView 中启用 JS:
myWebView.getSettings().setJavaScriptEnabled(true);
添加JS接口:
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");
}
我有一个带有按钮的简单页面,当按下按钮时,使用异步剪贴板 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 应用程序可能需要额外的权限才能访问剪贴板,但根据 https://developer.android.com/about/versions/10/privacy/changes#clipboard-data,我的应用程序在获得焦点时应该有权限。实际上,以下代码有效:
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" />
这没有任何作用。
所以这可能不是应用级别权限的问题。
发生了什么事?
如何让异步剪贴板 API 调用在 Webview 中工作?
OS: Android 10 Q
网络视图:v. 81.0.4044.111
剪贴板 API 的 writeText
方法文档说,我们需要使用权限 API 获得 clipboard-write
权限,但 navigator.permission
在 WebView 中未定义,可能是因为他们不想将 Web 权限与 Android OS 权限混合使用。
还有一种方法可以将文本从 Android WebView 复制到剪贴板:通过从 WebView JavaScript (JS) 代码调用本机 Java 方法。
在 WebView 中启用 JS:
myWebView.getSettings().setJavaScriptEnabled(true);
添加JS接口:
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");
}