Cuộc gọi API của Clipboard ném Not ALLowedError mà không gọi onPermissionRequest ()


10

Tôi có một trang đơn giản với một nút, khi nhấn, sử dụng API Clipboard Async để ghi vào bảng tạm.

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

Điều này hoạt động trên cả Chrome và Firefox, máy tính để bàn và thiết bị di động. Tuy nhiên, trên Android Webview, nó đưa ra lỗi sau:

NotAllowError: Write permission denied.


Tôi hình dung mình cần ghi đè WebChromeClient.onPermissionRequest()để cấp quyền, nhưng kỳ lạ onPermissionRequest()là dường như không được gọi, và lỗi tương tự vẫn được đưa ra.

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

Tôi vẫn nhận được cùng một lỗi:

NotAllowError: Write permission denied.

Ngoài ra Logcat đăng nhập không có gì.


Tôi nghi ngờ có thể Ứng dụng Android của tôi yêu cầu quyền truy cập bổ sung để truy cập vào bảng tạm, nhưng theo https://developer.android.com/about/versions/10/privacy/changes#clipboard-data , Ứng dụng của tôi nên có quyền khi tập trung vào . Thật vậy, đoạn mã sau hoạt động:

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

Tôi cũng đã tuyên bố như sau trong AndroidManifest.xmltrường hợp hành động yêu cầu sự cho phép cần có sự cho phép:

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

Điều này không làm gì cả.

Vì vậy, nó có thể không phải là một vấn đề với sự cho phép cấp độ ứng dụng.


Chuyện gì đang xảy ra vậy?

Làm cách nào tôi có thể nhận các lệnh gọi API Clipboard Async để hoạt động trong Webview?


HĐH: Android 10 Q

Webview: câu 81.0.4044.111


Câu hỏi tương tự, cũng không có câu trả lời: stackoverflow.com/questions/61429649/ từ
BDL


Có thể là một lỗi.
Travis J

@hereticMonkey thx cho liên kết nhưng tôi không nghĩ nó thay đổi gì cả. Nó tuyên bố "cố gắng đọc hoặc ghi dữ liệu clipboard sẽ tự động nhắc người dùng cho phép nếu nó chưa được cấp", ngụ ý không có cách rõ ràng nào để yêu cầu quyền này trong JS ngoài việc chỉ sử dụng bảng tạm, mà tôi tin là đúng Như đã đề cập trong câu hỏi, khi tôi làm điều đó trong môi trường Webview, onPermissionRequest()trên thực tế chưa bao giờ được gọi.
cyqsimon

Câu trả lời:


2

Các writeTexttài liệu phương pháp của Clipboard API nói rằng, chúng ta cần có được sự clipboard-writecho phép bằng quyền api. nhưngnavigator.permission không được xác định trong webview, có thể vì họ không muốn trộn các quyền web với quyền os của Android.

Có một cách nữa để chúng ta có thể sao chép văn bản vào clipboard từ webview android (bằng cách gọi phương thức java gốc từ mã javascript của webview).

Trước hết, bật javascript trên webview:

myWebView.getSettings().setJavaScriptEnabled(true);

Sau đó thêm giao diện javascript:

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

Tạo phương thức sẽ sao chép văn bản vào clipboard bằng cách sử dụng 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);
    }
}

Bây giờ bạn chỉ có thể gọi phương thức trên từ testClipboardphương thức:

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

  NativeAndroid.copyToClipboard("Clipboard API Test");
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.