Q&A

Android端末でLIFF内のクリップボードコピー(navigator.clipboard.writeText)に失敗する

前提・実現したいこと

Reactを使ったLIFFアプリを実装しており、画面内に表示しているテキストをJavaScript(navigator.clipboard)でコピーしたいと思っております。

発生している問題・エラーメッセージ

navigator.clipboard.writeTextを実行すると、Android端末のみ「NotAllowedError: Write permission denied」が発生します。 iOSでは発生せず、2021年9月頃に試した際はエラーになりませんでした。

該当のソースコード

ボタン押下時に下記の関数を実行しています。

 async copyTextToClipboard(text) {
    try {
      await navigator.clipboard.writeText(text);
      console.log('Async: Copying to clipboard was successful!');
      return true;
    } catch (err) {
      alert('コピーに失敗しました。');
      console.error('Async: Could not copy text: ', err);
      return false;
    }
  }

試したこと

navigator.permissionsでパーミッションを確認しようとしましたが、LIFFブラウザではnavigator.permissionsを取得できませんでした。

補足情報(FW/ツールのバージョンなど)

React 17.0.2 事象が発生しているAndroid端末:Galaxy S20 5G LINEバージョン:11.19.1 Androidバージョン:10 Android System WebView:95.0.4638.74 上記の他にも複数端末で発生しております。

  • 1
  • 1
  • 1746
  • twitter facebook

自己解決しました。 Clipboard APIの失敗時、非推奨のexecCommand('copy')を実行するように変更すると、Android端末でもコピーできました。

async copyTextToClipboard(text) {
    try {
      await navigator.clipboard.writeText(text);
      console.log('Async: Copying to clipboard was successful!');
      return true;
    } catch (err) {
      try {
        console.log('Async: Could not copy text: ', err);
        var input = document.createElement('input');
        document.body.appendChild(input);
        input.value = text;
        input.select();
        const result = document.execCommand('copy');
        document.body.removeChild(input);
        if (!result) {
          throw new Error('document.execCommand failed');
        }
        console.log('document.execCommand: Copying to clipboard was successful!');
        return true;
      } catch (err) {
        alert('コピーに失敗しました。');
        console.error('document.execCommand: Could not copy text: ', err);
        return false;
      }
    }
  }

非推奨の機能を使用するのは避けたいところですが、今のところ問題なさそうですのでこちらで実装いたします。

  • 0
本当によろしいですか? question.vm