如何从 Android WebView 中获取 JavaScript 函数的返回值到应用程序 – Java

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

How to get a javascript function's return value from android webview to application - Java

问题

String fileName = MyWebView.loadUrl("javascript:android.onData(returnFileName())");
英文:

I want to get the return value of a javascript function inside Android webview to be made accessible to the android application and get it converted to a string.

So I put this code:

String fileName = MyWebView.loadUrl("javascript:android.onData(returnFileName())");

But then it shows this error: Incompatible types. Found: 'void', required: 'java.lang.String'.

How to fix this?

Edit:
Actually I have an input field where the user can enter the name of a file generated as base64(data:)(which was actually a blob but I converted it). On Firefox and Chrome the downloaded file have the name user entered (I used a.download=document.getElementById.value for that) but on webview while downloading(by setting Download listener) the file I had to process the (data:) to a working URI. Now I would like to add the name entered by User to the downloaded file. For that I need to get the value of input field inside webview to Android application.

Thanks in advance.

答案1

得分: 1

WebView的loadUrl()方法不会返回任何东西,而是可以使用evaluateJavascript()方法。在onPageFinished()方法中注入JavaScript,并通过ValueCallback接口的onReceiveValue()方法获取返回值。请确保你的JavaScript函数有返回值。注意:evaluateJavascript()仅在Android 4.4(API级别19)及以上版本可用。

英文:

The prototype of WebView's loadUrl() is:

public void loadUrl(String url)

As such, loadUrl() will never return anything, certainly not the filename as you expect.

Instead, you can use the evaluateJavascript() method of the WebView:

  • Create a JavaScript interface in your Java application by extending the WebViewClient class and overriding its onPageFinished() method. In there, inject JavaScript into the WebView and get its return value:
webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        webView.evaluateJavascript("yourJavaScriptFunction()", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
                // value is the return value of your JavaScript function
            }
        });
    }
});
  • In your JavaScript function, make sure to return a value:
function yourJavaScriptFunction() {
    return "hello world";
}
  • Once the WebView has finished loading the page, the onReceiveValue() method of the ValueCallback interface will be called, and you can get the return value of your JavaScript function from the value parameter.

Note: evaluateJavascript() is only available on Android 4.4 (API level 19) and above. If you're targeting an earlier version of Android, you'll need to use the loadUrl() method to execute your JavaScript and get its return value.

答案2

得分: 0

你确定已启用 JavaScript 吗?

getSettings().setJavaScriptEnabled(true);

还可以尝试访问此站点。他们提供了有关 Android WebView 的一些有用信息。

英文:

Are you sure you enabled JavaScript?

getSettings().setJavaScriptEnabled(true);

Also try visiting <a href="https://www.digitalocean.com/community/tutorials/android-webview-example-tutorial">this site</a>. They have some useful information on Android WebView.

答案3

得分: 0

这是我的尝试后与@Introspective的答案进行实验后对我有效的内容;我在这里发布是因为任何未来的访问者可能会发现它有帮助。替代onPageFinished(),我将evaluateJavascript()放在下载监听器中。由于结果是JSON值,需要一个JsonReader。

MyWebView.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -&gt; {
    if (url.startsWith(&quot;data:&quot;)) {
       MyWebView.evaluateJavascript(&quot;returnfileName()&quot;, string -&gt; {
           JsonReader jsonReader = new JsonReader(new StringReader(string));
           jsonReader.setLenient(true);//this is needed because I am returning  a single value
    if(jsonReader.peek() != JsonToken.NULL) {
           String fileName = jsonReader.nextString();
           //现在我可以按照我的意愿使用String fileName。
           //其余的代码
   }
}

Javascript函数returnFileName()

function returnfileName(){
  var fileName;
  if (document.getElementById(&quot;输入字段的ID&quot;).value===&quot;&quot;){ 
  fileName = &quot;如果用户未输入任何文件名,则为默认文件名&quot;;
  }
  else{
  fileName = document.getElementById(&quot;输入字段的ID&quot;).value;}
  }
  return fileName;
}

由于evaluateJavascript()是void,我不得不将其余的代码放在evaluateJavascript()本身内部,否则String fileName将对它们不可访问(void没有返回值)。

英文:

So this is what worked for me after experimenting with the answer by @Introspective; I am posting here because any future visitors may find it helpful.
Instead of onPageFinished(), I put evaluateJavascript() inside download listener. A JsonReader was required as the result is a JSON value.

MyWebView.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -&gt; {
    if (url.startsWith(&quot;data:&quot;)) {
       MyWebView.evaluateJavascript(&quot;returnfileName()&quot;, string -&gt; {
           JsonReader jsonReader = new JsonReader(new StringReader(string));
           jsonReader.setLenient(true);//this is needed because I am returning  a single value
    if(jsonReader.peek() != JsonToken.NULL) {
           String fileName = jsonReader.nextString();
           //Now I can use the String fileName as I wish.
           //Rest of the code
   }
}

Javascript function returnFileName()

function returnfileName(){
  var fileName;
  if (document.getElementById(&quot;id of input field&quot;).value===&quot;&quot;){ 
  fileName = &quot;Default file name in case user didn&#39;t enter any filename&quot;;
  }
  else{
  fileName = document.getElementById(&quot;id of input field&quot;).value;}
  }
  return fileName;
}

Since evaluateJavascript() is a void, I had to put rest of the code to download the file inside the evaluateJavascript() itself, because otherwise String fileName will not be accessible for them (void doesn't have a return value).

huangapple
  • 本文由 发表于 2023年4月17日 21:42:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76035813.html
匿名

发表评论

匿名网友

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

确定