Вызовите Android share intent из JavaScript в WebView

#javascript #android #kotlin #webview #share-intent

#javascript #Android #kotlin #webview #поделиться-намерение

Вопрос:

Я пытаюсь использовать код этой статьи для запуска share intent моего приложения для Android (kotlin) из JavaScript в WebView. Вот код, который я использую для запуска:

 class MainActivity : AppCompatActivity() {  object AndroidJSInterface {
    @JavascriptInterface
    fun onClicked() {
      Log.d("HelpButton", "Help button clicked")
    }
  }  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)    val webViewClient = object : WebViewClient() {
      override fun onPageFinished(view: WebView, url: String) {
        loadJs(view)
      }
    }    val webView = WebView(this)
    webView.webViewClient = webViewClient
    webView.settings.javaScriptEnabled = true
    webView.addJavascriptInterface(AndroidJSInterface, "Android")    setContentView(webView)
    webView.loadUrl("https://vuetifyjs.com/en/getting-started/quick-start")
  }  private fun loadJs(webView: WebView) {
    webView.loadUrl(
      """javascript:(function f() {
        var btns = document.getElementsByTagName('button');
        for (var i = 0, n = btns.length; i < n; i  ) {
          if (btns[i].getAttribute('aria-label') === 'Support') {
            btns[i].setAttribute('onclick', 'Android.onClicked()');
          }
        }
      })()"""
    )
  }
}
 

Я изменил функцию в интерфейсе AndroidJSInterface следующим образом:

     @JavascriptInterface
    fun shareUrl(url: String? = "") {
        Log.d("JavaScript", "shareUrl: "   url)
        if( !url.isNullOrEmpty() )
        {
            val intent= Intent()
            intent.action=Intent.ACTION_SEND
            intent.putExtra(Intent.EXTRA_TEXT, url)
            intent.type="text/plain"
            startActivity(Intent.createChooser(intent, "Share To:"))
        }
    }
 

Проблема, с которой я сталкиваюсь, заключается в том, что startActivity здесь не распознается (я получаю «Неразрешенную ссылку: startActivity»). Как я могу получить доступ к startActivity из этой части моего кода?

Спасибо за вашу помощь,

Кристоф

Ответ №1:

 public abstract void startActivity(@RequiresPermission Intent intent);
 

Этот метод изначально доступен в Context классе, а затем в Activity и ContextWrapper , поскольку они являются дочерними элементами Context класса.

AndroidJSInterface является простым объектом, а не прямым или косвенным дочерним элементом Context , следовательно startActivity , не распознается в этом блоке, поскольку this в этом методе относится к instance AndroidJSInterface типу of, который не является дочерним элементом Context . Итак, чтобы обратиться к this или instance MainActivity к shareUrl методу in.

Вы можете сделать это в Kotlin

 this@MainActivity.startActivity(Intent.createChooser(intent, "Share To:"))
 

или в Java

 MainActivity.this.startActivity(Intent.createChooser(intent, "Share To:"));
 

Комментарии:

1. Действие, в котором я использую интерфейс Javascript, называется WebActivity. Итак, я попытался ‘this@WebActivity.startActivity (Намерение.createChooser(намерение, «Поделиться с:»))’ но я получил эту ошибку: неразрешенная ссылка: @WebActivity

2. можете ли вы добавить этот фрагмент к своему вопросу

3. Я нашел решение, которое я опубликовал ниже — спасибо за ответ, это подтолкнуло меня к поиску причины, по которой этот @WebActivity работал не так, как я ожидал изначально.

Ответ №2:

Я нашел решение, хотя я не очень понимаю, почему это работает:

Я заменил:

 @JavascriptInterface
fun shareUrl(url: String? = "") {
    Log.d("JavaScript", "shareUrl: "   url)
    if( !url.isNullOrEmpty() )
    {
        val intent= Intent()
        intent.action=Intent.ACTION_SEND
        intent.putExtra(Intent.EXTRA_TEXT, url)
        intent.type="text/plain"
        startActivity(Intent.createChooser(intent, "Share To:"))
    }
}
 

Автор::

 private inner class JavascriptInterface
{
    @android.webkit.JavascriptInterface
    fun shareUrl(url: String? = "") {
        Log.d("JavaScript", "shareUrl: "   url)
        // TODO: debug startActivity to launch Android sharing screen
        if( !url.isNullOrEmpty() )
        {
            val intent= Intent()
            intent.action=Intent.ACTION_SEND
            intent.putExtra(Intent.EXTRA_TEXT, url)
            intent.type="text/plain"
            this@WebActivity.startActivity(Intent.createChooser(intent, "Share To:"))
        }
    }
}