在WebView中发送一个大请求。

huangapple go评论60阅读模式
英文:

Sending a large request in a WebView

问题

I have some srt files and I want to translate them into Kurdish because the lack of translation in this language, instead of using an API which I can't afford, I'm using WebView to pass the string inside the srt to the query, and to get the translation using a Javascript interface.

This works fine when the string is small, for example a few thousand characters, but when passing the whole string inside the srt I get an error (of course) because of the large request.

So I need help with finding a way to make this work.

This is the function for setting up the WebView:

fun setupWebView(
    input: String,
    from: String,
    into: String,
    webView: WebView,
    resultHandler: (String) -> Unit
) {
    val url =
        "https://translate.google.com/?sl=$from&tl=$into&text=${input.dropLast(70000)}&op=translate"

    webView.addJavascriptInterface(JsInterface, "JsInterface")

    webView.loadUrl(url)

    JsInterface.setResultCallback {
        resultHandler(it)
    }

    webView.settings.javaScriptEnabled = true

    webView.webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            view?.postDelayed({
                injectJavascript(view)
            }, 1000)
        }
    }
}

(Note: I have retained the code as is without translation, as per your request.)

英文:

I have some srt files and I want to translate them into Kurdish because the lack of translation in this language, instead of using an API which I can't afford, I'm using WebView to pass the string inside the srt to the query, and to get the translation using a Javascript interface.

This works fine when the string is small, for example a few thousand characters, but when passing the whole string inside the srt I get an error (of course) because of the large request.

So I need help with finding a way to make this work.

This is the function for setting up the WebView:

fun setupWebView(
    input: String,
    from: String,
    into: String,
    webView: WebView,
    resultHandler: (String) -> Unit
) {
    val url =
        "https://translate.google.com/?sl=$from&tl=$into&text=${input.dropLast(70000)}&op=translate"

    webView.addJavascriptInterface(JsInterface, "JsInterface")

    webView.loadUrl(url)

    JsInterface.setResultCallback {
        resultHandler(it)
    }


    webView.settings.javaScriptEnabled = true


    webView.webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            view?.postDelayed({
                injectJavascript(view)
            }, 1000)
        }
    }
}

答案1

得分: 1

这似乎与你的另一个问题有关,因为它也涉及到处理Android WebView中loadUrl函数的限制

WebView中的loadUrl方法接受一个字符串URL来加载网页。但是,URL有一个最大长度限制。根据HTTP协议,没有限制,但大多数Web浏览器和服务器限制URL长度以便管理。被广泛接受的最大长度为2000个字符。如果你试图通过URL查询参数将一个非常大的字符串传递给loadUrl,它很容易超过这个限制,从而导致问题。

在你的情况下,似乎你正在尝试通过将它作为URL参数传递来翻译大量文本。这很可能超出了URL长度限制,导致错误。

你需要找到一种方法,将大字符串分成足够小的块,以适应URL长度限制,然后分别处理每个块。就像你的第二个问题中所描述的:将文本分成块,为每个块创建一个URL,然后依次在WebView中加载每个URL。

然而,这种方法有限制。逐块翻译文本可能会导致不正确的翻译,因为在每次翻译时没有考虑整个文本的上下文。而且,像Google翻译这样的自动翻译服务有使用政策,可能会阻止或限制这种用法。

更合适的做法是使用专为大量文本设计的翻译API,但你提到这对你来说不是一个经济实惠的选择。在这种情况下,你可以考虑寻找其他免费或更经济实惠的翻译API,或者考虑使用可以在设备上本地运行的机器学习模型进行翻译。

英文:

This seems related to your other question, in the sense that it is also dealing with the limitations of the loadUrl function in Android's WebView.

The loadUrl method in WebView accepts a string URL to load a webpage. However, URLs have a maximum length limit. According to the HTTP protocol, there is no limit, but most web browsers and servers limit URL length to keep them manageable. The widely accepted maximum length is 2000 characters. If you are trying to pass a very large string to loadUrl through a URL query parameter, it could easily exceed this limit, leading to issues.

In your case, it seems you are trying to translate a large amount of text by passing it as a URL parameter to a translation website. This is likely exceeding the URL length limit, causing an error.

You would need to find a way to divide the large string into smaller chunks that are small enough to fit within the URL length limit, and then process each chunk separately. As in your second question: divide the text into chunks, create a URL for each chunk, and then load each URL one at a time in the WebView.

However, this approach has limitations. Translating text chunk by chunk may lead to incorrect translations, as the context of the whole text is not taken into account during each translation. Also, automated translation services like Google Translate have usage policies that could prevent or limit this kind of usage.

It would be more appropriate to use a translation API designed for large amounts of text, but you mentioned that this is not an affordable option for you. In that case, you might want to look for other free or more affordable translation APIs, or consider using machine learning models for translation that you could run locally on the device.

答案2

得分: 0

以下是您提供的代码的中文翻译:

import android.os.Handler
import android.os.Looper
import android.webkit.WebView
import android.webkit.WebViewClient
import java.io.ByteArrayOutputStream
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

fun setupWebView(
    input: String,
    from: String,
    into: String,
    webView: WebView,
    resultHandler: (String) -> Unit
) {
    val postData = "sl=$from&tl=$into&text=${input.dropLast(70000)}&op=translate"

    webView.addJavascriptInterface(JsInterface, "JsInterface")
    webView.settings.javaScriptEnabled = true

    webView.webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            view?.postDelayed({
                injectJavascript(view)
            }, 1000)
        }
    }

    val handler = Handler(Looper.getMainLooper())

    Thread {
        try {
            val postUrl = URL("https://translate.google.com")
            val conn = postUrl.openConnection() as HttpURLConnection

            conn.requestMethod = "POST"
            conn.doOutput = true

            conn.connectTimeout = 5000
            conn.readTimeout = 5000

            val out = conn.outputStream
            val writer = OutputStreamWriter(out, "UTF-8")

            writer.write(postData)
            writer.flush()
            writer.close()

            val inputStream = conn.inputStream
            val buffer = ByteArrayOutputStream()

            inputStream.use { input ->
                val data = ByteArray(1024)
                var bytesRead: Int
                while (input.read(data).also { bytesRead = it } != -1) {
                    buffer.write(data, 0, bytesRead)
                }
            }

            val html = buffer.toString("UTF-8")

            handler.post {
                webView.loadDataWithBaseURL("https://translate.google.com", html, "text/html", "UTF-8", null)
            }

            JsInterface.setResultCallback { resultHandler(it) }
        } catch (e: Exception) {
            // 处理异常情况
        }
    }.start()
}

如果您需要更多帮助或有其他问题,请随时提出。

英文:
import android.os.Handler
import android.os.Looper
import android.webkit.WebView
import android.webkit.WebViewClient
import java.io.ByteArrayOutputStream
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL

fun setupWebView(
    input: String,
    from: String,
    into: String,
    webView: WebView,
    resultHandler: (String) -> Unit
) {
    val postData = "sl=$from&tl=$into&text=${input.dropLast(70000)}&op=translate"

    webView.addJavascriptInterface(JsInterface, "JsInterface")
    webView.settings.javaScriptEnabled = true

    webView.webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)
            view?.postDelayed({
                injectJavascript(view)
            }, 1000)
        }
    }

    val handler = Handler(Looper.getMainLooper())

    Thread {
        try {
            val postUrl = URL("https://translate.google.com")
            val conn = postUrl.openConnection() as HttpURLConnection

            conn.requestMethod = "POST"
            conn.doOutput = true

            conn.connectTimeout = 5000
            conn.readTimeout = 5000

            val out = conn.outputStream
            val writer = OutputStreamWriter(out, "UTF-8")

            writer.write(postData)
            writer.flush()
            writer.close()

            val inputStream = conn.inputStream
            val buffer = ByteArrayOutputStream()

            inputStream.use { input ->
                val data = ByteArray(1024)
                var bytesRead: Int
                while (input.read(data).also { bytesRead = it } != -1) {
                    buffer.write(data, 0, bytesRead)
                }
            }

            val html = buffer.toString("UTF-8")

            handler.post {
                webView.loadDataWithBaseURL("https://translate.google.com", html, "text/html", "UTF-8", null)
            }

            JsInterface.setResultCallback { resultHandler(it) }
        } catch (e: Exception) {
            // Handle exceptions here
        }
    }.start()
}

huangapple
  • 本文由 发表于 2023年5月21日 19:19:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76299648.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定