Panggilan API Clipboard melempar NotAllowedError tanpa memohon onPermissionRequest ()

10

Saya memiliki halaman sederhana dengan tombol, yang ketika ditekan, menggunakan Async Clipboard API untuk menulis ke 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));
}

Ini berfungsi baik di Chrome dan Firefox, desktop dan seluler. Namun di Android Webview ia melempar kesalahan berikut:

NotAllowError: Write permission denied.


Saya pikir saya perlu mengganti WebChromeClient.onPermissionRequest()untuk memberikan izin, tetapi anehnya onPermissionRequest()tampaknya tidak dipanggil, dan kesalahan yang sama masih terjadi.

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

Saya tetap mengalami masalah yang sama:

NotAllowError: Write permission denied.

Logcat juga tidak mencatat apa pun.


Saya menduga mungkin Aplikasi Android saya memerlukan izin tambahan untuk mengakses clipboard, tetapi menurut https://developer.android.com/about/versions/10/privacy/changes#clipboard-data , Aplikasi saya harus memiliki izin ketika memiliki fokus . Memang, kode berikut berfungsi:

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

Saya juga menyatakan sebagai berikut AndroidManifest.xmljika tindakan meminta izin memerlukan izin:

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

Ini tidak melakukan apa pun.

Jadi itu mungkin bukan masalah dengan izin tingkat Aplikasi.


Apa yang terjadi?

Bagaimana saya bisa mendapatkan panggilan API Async Clipboard untuk bekerja di Webview?


OS: Android 10 Q

Webview: v. 81.0.4044.111

cyqsimon
sumber
Pertanyaan serupa, juga tidak ada jawaban: stackoverflow.com/questions/61429649/…
BDL
Saya tidak tahu apa-apa tentang Android, tetapi artikel dari Google ini merujuk pada penggunaan API Izin (dari browser) .
Monyet sesat
Bisa jadi bug.
Travis J
@hereticMonkey thx untuk tautan tetapi saya tidak berpikir itu mengubah apa pun. Ini menyatakan "berusaha membaca atau menulis data clipboard akan secara otomatis meminta pengguna untuk izin jika belum diberikan", menyiratkan tidak ada cara eksplisit untuk meminta izin ini di JS selain hanya mencoba menggunakan clipboard, yang saya percaya itu benar. Seperti yang disebutkan dalam pertanyaan, ketika saya melakukan itu di lingkungan Webview, onPermissionRequest()sebenarnya tidak pernah dipanggil.
cyqsimon

Jawaban:

2

writeTextDokumen metode Clipboard API mengatakan, kita perlu mendapatkan clipboard-writeizin menggunakan Izin api. tapinavigator.permission tidak terdefinisi dalam tampilan web, mungkin karena mereka tidak ingin mencampur izin web dengan izin os android.

Ada satu lagi cara dimana kita dapat menyalin teks ke clipboard dari tampilan web android (dengan memanggil metode java asli dari kode javascript tampilan web).

Pertama-tama aktifkan javascript di tampilan web:

myWebView.getSettings().setJavaScriptEnabled(true);

Kemudian tambahkan antarmuka javascript:

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

Buat metode yang akan menyalin teks ke clipboard menggunakan 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);
    }
}

Sekarang Anda bisa memanggil metode di atas dari testClipboardmetode:

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

  NativeAndroid.copyToClipboard("Clipboard API Test");
}
Ankit Makwana
sumber