Виклик буфера обміну API кидає NotAllowedError без виклику onPermissionRequest ()


12

У мене проста сторінка з кнопкою, яка при натисканні використовує API Async 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 він видає таку помилку:

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 Async Clipboard працювати в Webview?


ОС: Android 10 Q

Веб-перегляд: v. 81.0.4044.111


Подібне запитання, також немає відповіді: stackoverflow.com/questions/61429649/…
BDL


Може бути помилка.
Travis J

@hereticMonkey thx для посилання, але я не думаю, що це щось змінює. У ньому йдеться про те, що "спроба читання або записування даних буфера обміну автоматично сповістить користувача про дозвіл, якщо він ще не був наданий", маючи на увазі, що немає явного способу вимагати цього дозволу в JS, крім простої спроби використовувати буфер обміну, який я вірити правді. Як згадувалося в запитанні, коли я це роблю в середовищі Webview, onPermissionRequest()насправді ніколи не використовувався.
cyqsimon

Відповіді:


4

writeTextДокументи API буфера обміну говорить, що нам потрібно отримати clipboard-writeдозвіл, використовуючи дозволи Peri. але navigator.permissionне визначено у веб-перегляді, можливо, тому, що вони не хочуть змішувати веб-дозволи з дозволами ОС Android.

Є ще один спосіб, за допомогою якого ми можемо скопіювати текст у буфер обміну з веб-перегляду Android (за допомогою виклику нативної методи java з коду JavaScript 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");
}

Я здивований, що Android Webviewне здійснив navigator.permission. Ну, це ганьба. Я поки що використаю ваше вирішення. Дякую.
циксимон

1
Так, це дивно, адже інші дозволи, такі як камера, мікрофон, працюють через PermissionRequestвнутрішній перегляд.
Анкіт Маквана
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.