La chiamata API negli Appunti genera NotAllowedError senza richiamare onPermissionRequest ()


10

Ho una semplice pagina con un pulsante che, se premuto, utilizza l'API Async Clipboard per scrivere negli appunti.

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

Funziona su Chrome e Firefox, desktop e mobile. Tuttavia su Android Webview genera il seguente errore:

NotAllowError: Write permission denied.


Ho pensato di dover eseguire l'override WebChromeClient.onPermissionRequest()per concedere l'autorizzazione, ma stranamente onPermissionRequest()non sembra essere stato invocato e lo stesso errore viene ancora generato.

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

Ottengo ancora lo stesso errore:

NotAllowError: Write permission denied.

Anche Logcat non ha registrato nulla.


Sospettavo che forse la mia app per Android richiedesse ulteriori autorizzazioni per accedere agli Appunti, ma secondo https://developer.android.com/about/versions/10/privacy/changes#clipboard-data , la mia app dovrebbe avere l'autorizzazione quando è attiva . In effetti, il seguente codice funziona:

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

Ho anche dichiarato quanto segue nel AndroidManifest.xmlcaso in cui l'azione di richiesta di autorizzazione richieda l'autorizzazione:

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

Questo non ha fatto nulla.

Quindi probabilmente non è un problema con l'autorizzazione a livello di app.


Che cosa sta succedendo?

Come posso far funzionare le chiamate API degli Appunti Async in Webview?


Sistema operativo: Android 10 Q

Webview: v. 81.0.4044.111


Domanda simile, anche nessuna risposta: stackoverflow.com/questions/61429649/…
BDL


Potrebbe essere un bug.
Travis J,

@hereticMonkey thx per il link ma non credo che cambi nulla. Afferma che "il tentativo di leggere o scrivere i dati degli Appunti richiede automaticamente all'utente l'autorizzazione se non è già stata concessa", il che implica che non esiste un modo esplicito per richiedere tale autorizzazione in JS se non il semplice tentativo di utilizzare gli Appunti, che credere è vero. Come menzionato nella domanda, quando lo faccio in un ambiente Webview, onPermissionRequest()in realtà non è mai stato invocato.
cyqsimon,

Risposte:


2

I writeTextdocumenti del metodo dell'API degli Appunti dicono che dobbiamo ottenere l' clipboard-writeautorizzazione usando API api. ma navigator.permissionnon è definito in Webview, forse perché non vogliono mescolare le autorizzazioni Web con le autorizzazioni del sistema operativo Android.

C'è un altro modo in cui possiamo copiare il testo negli Appunti da Android Webview (chiamando il metodo Java nativo dal codice JavaScript Webview).

Prima di tutto abilitare javascript su webview:

myWebView.getSettings().setJavaScriptEnabled(true);

Quindi aggiungi l'interfaccia javascript:

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

Crea un metodo che copierà il testo negli appunti usando 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);
    }
}

Ora puoi semplicemente chiamare il metodo sopra dal testClipboardmetodo:

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

  NativeAndroid.copyToClipboard("Clipboard API Test");
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.