Вызов API буфера обмена генерирует NotAllowedError без вызова onPermissionRequest () - PullRequest
10 голосов
/ 16 апреля 2020

У меня есть простая страница с кнопкой, которая при нажатии использует API буфера обмена Asyn c для записи в буфер обмена.

<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 -данным , мое приложение должно иметь разрешение, когда оно имеет фокус , Действительно, работает следующий код:

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" />

Это ничего не сделало.

Так что, вероятно, это не проблема с разрешением уровня приложения.


Что происходит?

Как я могу получить Asyn c Буфер обмена Вызов API для работы в Webview?


ОС: Android 10 Q

Webview: v. 81.0.4044.111

1 Ответ

2 голосов
/ 01 мая 2020
В методе

API буфера обмена writeText говорится, что нам нужно получить разрешение clipboard-write с помощью Permissions api. но navigator.permission не определено в веб-просмотре, возможно, потому, что они не хотят смешивать веб-разрешения с android os-разрешениями.

Есть еще один способ, которым мы можем копировать текст в буфер обмена из android веб-просмотр (вызывая нативный java метод из веб-просмотра javascript код).

Прежде всего включите 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");
}
...