Is it possible to get data from HTML forms into android while using webView?
Asked Answered
T

9

29

I'm making a very simple form in HTML which is viewed in android using the webview which takes in your name using a textbox and when you click on the button, it displays it into a paragraph and it's made using both html and javascript. This is my html code:

<!DOCTYPE html>
<html>
<body>
<p> Write your name and win your favorite game console name and win it! The winners will be announced in 4 days.</p>
Type your name here: <input id="thebox" type="text" name="value" value=""><br>

    <button onclick="myFunction()">Try it</button>

    <p id="demo"></p>

    <script>
    function myFunction() {
        var x = document.getElementById("thebox").value;
        document.getElementById("demo").innerHTML = x;
    }
    </script>

    </body>
    </html>

NEW EDITED FORM

<form name="albert" action="" method="POST">

 <label for="firstname"> First Name </label>
 <br /><br />

 <input type="text" name="firstname" id="firstname" />

 <input type="submit" name="sbumit" value="Submit" />


</form>

I want to get the value from the input box called "thebox" in a variable in android on the button click and I tried lots of stuff before and I followed a method where you inject a JS file but since I know nothing about JS so I did fail trying that and here is the file that I put in my project and the file is called inject.js:

document.getElementsByTagName('form')[0].onsubmit = function () {
    var objPWD, objAccount, objSave;
    var str = '';
    var inputs = document.getElementsByTagName('thebox');
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].name.toLowerCase() === 'thebox') {
            objAccount = inputs[i];
        }
    }
    if(objAccount != null) {
        str += objAccount.value;
    }
    if(objPWD != null) {
        str += ' , ' + objPWD.value;
    }
    if(objSave != null) {
        str += ' , ' + objSave.value;
    }
    window.AndroidInterface.processHTML(str);
    return true;
};

And later as I followed that article it said that I need to put some stuff in my MainActivity but since I'm using webview for the first time, I couldn't understand much and heres the code I put into my MainActivity:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WebView webView = new WebView(this);
        this.setContentView(webView);

        // enable javascript
        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webView.addJavascriptInterface(new JavaScriptInterface(), "AndroidInterface");

        // catch events
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                try {
                    view.loadUrl("javascript:" + buildInjection());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        webView.loadUrl("http://someurl.com");
    }

A nested class that I made in my MainActivity:

class JavaScriptInterface {
        @JavascriptInterface
        public void processHTML(String formData) {
            Log.d("AWESOME_TAG", "form data: " + formData);
        }
    }

And finally the method that injects the code:

private String buildInjection() throws IOException {
        StringBuilder buf = new StringBuilder();
        InputStream inject = getAssets().open("inject.js");// file from assets
        BufferedReader in = new BufferedReader(new InputStreamReader(inject, "UTF-8"));
        String str;
        while ((str = in.readLine()) != null) {
            buf.append(str);
        }
        in.close();

        return buf.toString();
    }

I want to get value from the html form(the-input-box) that I show in a webview in Android and is it really possible to do that and if yes how and please explain? Thanks and also please tell in what variable will I get the value.

Toadinthehole answered 30/11, 2016 at 13:5 Comment(4)
check my answerHomework
I have updated my answer.Homework
have you checked my answer.? ask me if you have any doubtsHomework
To get data from a WebView in Android : https://mcmap.net/q/236040/-how-to-get-return-value-from-javascript-in-webview-of-androidDarwinism
H
39
    Webview browser=(WebView)view.findViewById(R.id.webChart);
    browser.getSettings().setJavaScriptEnabled(true);
    browser.addJavascriptInterface(new WebAppInterface(getActivity()), "Android");
    browser.loadUrl("file:///android_asset/yourHtmlFileName.html");

add this interface class, WebAppInterface

public class WebAppInterface {
 Context mContext;
 String data;

 WebAppInterface(Context ctx){
    this.mContext=ctx;
 } 


 @JavascriptInterface
 public void sendData(String data) {
    //Get the string value to process
      this.data=data;
 }
}

your HTML code data

 function loadChartData() {
  var x = document.getElementById("thebox").value;
   Android.sendData(x);
 }

call this function when the html button click in android webview

UPDATE

1) By default javascript is disabled in webview . to enable it, get the settings of the webview and call the setJavaScriptEnabled(true); to true.

2) to create the interface between your Javascript code and your android code, you need to create Javacript interface class.

3) bind the interface between your javascript code to android code, you need to pass the reference of the interface class and an interface name that your javaScript can call to access the class.

4) pass the html file path to load into the webview(browser).

5) create the interface class like below(WebAppInterface).

see this link for more details https://developer.android.com/guide/webapps/webview.html

6) in HTML file, create the button and add the click listener to that button and call the sendData("your value") function with interface name(Here Android).

Thats all. you can pass the value from html to your android code.

Homework answered 8/12, 2016 at 7:40 Comment(11)
Hey, sorry for late response. I'm having trouble with the getActivity method. I really need help with this...Toadinthehole
getActivity method is not working, it says cannot resolve the method.Toadinthehole
how did you try? from fragment or activity?Homework
I put this code in my main activity's onCreate() method: browser.addJavascriptInterface(new WebAppInterface(getActivity()), "Android");Toadinthehole
You should not use getActivity() from Activity . instead, use "this" keyword.Homework
Let us continue this discussion in chat.Toadinthehole
I used this and it says that it cannot be applied.Toadinthehole
My web developer is getting error "cannot find name 'Android' on his JavaScript. What he is missing? He is using typescriptSheeting
If getActivity() is not work try this - webView.addJavascriptInterface(new WebAppInterface(this), "Android");Plenipotent
@Homework is it possible to send an image file from javascript to Android Webviews?Plenipotent
Android will think that, javascript file can hack the system. so, this functionality is limited. instead of doing this, you can go with hybrid application development with the help of HTML,css and Javascript. there are lot of UI framework is there. example: ionic. ionicframework.com. and I am not enough experienced on hybrid application. You can follow up the documentation . then you can end up with great benefit which you are expecting.Homework
L
7

Yes you can, you can use javascript to get webpage content. Then use the webview jsInterface to return the content to you java code.

Refer this github project. and this answer and this article.

final Context myApp = this;

/* An instance of this class will be registered as a JavaScript interface */
class MyJavaScriptInterface
{
    @JavascriptInterface
    @SuppressWarnings("unused")
    public void processHTML(String html)
    {
        // process the html as needed by the app
    }
}

final WebView browser = (WebView)findViewById(R.id.browser);
/* JavaScript must be enabled if you want it to work, obviously */
browser.getSettings().setJavaScriptEnabled(true);

/* Register a new JavaScript interface called HTMLOUT */
browser.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");

/* WebViewClient must be set BEFORE calling loadUrl! */
browser.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url)
    {
        /* This call inject JavaScript into the page which just finished loading. */
        browser.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
    }
});

/* load a web page */
browser.loadUrl("http://lexandera.com/files/jsexamples/gethtml.html");

Hope this helps.

Litigable answered 3/12, 2016 at 13:2 Comment(1)
Please explain the bits of code and also tell where the data is coming(like the variable where the data comes into)Toadinthehole
T
4

For forms with method "GET" you can achieve this pretty simple just by overriding shouldOverrideUrlLoading method. Following solution works only if url was loaded through webview.loadUrl() method.

private class MWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) { 
        // submit will end-up with url like "data:,?firstname=SomeInput&sbumit=Submit"
        if (URLUtil.isDataUrl(url)) {
            url = url.replace(":,?", ":/?"); //to be able to properly parse Uri
            Uri uri = Uri.parse(url);

            //here you can get params by field name 
            String firstname = uri.getQueryParameter("firstname");

            //we handle this URL ourselves 
            return true;
        }

        return super.shouldOverrideUrlLoading(view, url);
    }
}
Thales answered 8/12, 2016 at 12:18 Comment(1)
This was a great option that I had not thought of (using get instead of post).Fick
H
2

To communicate a webView with native android, this is a simple way : in your js onClick on the button you should call url that contains your text, something like myPrefix://myData and in android

webView.setWebViewClient(new WebViewClient()
{
   @Override
   public boolean shouldOverrideUrlLoading(final WebView view, final String url) 
    {
     if(url.startsWith("myPrefix://")) 
      {
       //get your data by split url
       return true;
      }
 return false;

});
Hedjaz answered 8/12, 2016 at 13:44 Comment(0)
G
2

Yes, it is possible. Please try using the below code

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.web_view_layout);
    WebView webView = (WebView) findViewById(R.id.webView);
    webView.getSettings().setPluginState(WebSettings.PluginState.ON);
    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    try {
        progressDialog = new ProgressDialog(ActivityName);
    progressDialog.setMessage("Loading.."); progressDialog.setCancelable(false);
        webView.setWebViewClient(new MyWebViewClient());
        webView.loadUrl(YOUR_URL);
    } catch (Exception e) {
        e.toString();
    }
}

private class MyWebViewClient extends WebViewClient {

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
       view.loadUrl(url);
       progressDialog.dismissProgress();
       return true;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        progressDialog.dismissProgress();
    }
}
Gi answered 9/12, 2016 at 9:57 Comment(0)
P
2

@Shariq As many have already answered this question in a good way, but i think moreover you need clarification about how exactly data is flowing into the codes from webview to andorid so I won't waste bytes in writing that all redundant codes:

(I'm taking reference of your codes for better understanding ) Follow these steps in these codes to make better understanding:

Step 1:

We need to define some method on Android side that can accept some data from webview

@JavascriptInterface
//this 'formData' variable is going to accept the data from webview 
public void processHTML(String formData) {
    Log.d("AWESOME_TAG", "form data: " + formData);
}

Now the it's value will be available to java android side context.

Step 2:

here is your HTML side codes (webview). if the URL you are accessing in webview is yours then you can easily write these codes to html page but if you are accessing some third party URL still you can inject this js code into webview simply by following line of code:

...
//partial code
webView.load("javascript:function myFunction() { var x = document.getElementById('thebox').value; Android.processHTML(x); } myFunction();";
... 

So what's exactly happening here:

'x' is the variable in js holding the required value and then we are sending this 'x' variable to android context via method call Android.processHTML(x)

I hope it might help you in a better way

Postulant answered 9/12, 2016 at 10:48 Comment(3)
Do you know how I can retrieve that value from the js?Toadinthehole
@ShariqMusharaf i i have explained them in step 1 and 2.Postulant
Hi, i've tried your way. and i get error of undefined x, myFunction(). i can't retrieve thatIndecency
J
1

You can get data from WebView by catching alert messages.

Use WebChromeClient.

mWebview = (WebView)findViewById(R.id.yourwebviewlayout);
final class YourWebChromeClient extends WebChromeClient {
                @Override
                public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                    Toast.makeText(getApplicationContext(),
                            "alert message =  " + message,
                            Toast.LENGTH_SHORT).show();
                    result.confirm();
                    return true;
                }
            }
mWebview.setWebChromeClient(new YourWebChromeClient());
Joppa answered 6/12, 2016 at 10:52 Comment(0)
A
0

Best js to inject have used so far, it collects data from all forms on submit

document.getElementsByTagName("form")[0].addEventListener("submit", myFunction);
function myFunction()
{
    var data="";
    var inputs = document.forms[0].getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
        var field = inputs[i];
        if (field.type != 'submit' && field.type != 'reset' && field.type != 'button')
        data += '' + field.name + '=' + field.value+'\n';
    }
    window.AndroidInterface.processHTML(data);
    return true;
}
Agatha answered 10/7, 2018 at 15:11 Comment(0)
D
0

There are two steps :

1- The target element by ID or Class

 getFromPage = "(function() { " +
                        "return document.getElementsByClassName('title ft-3')[0].innerHTML;" +
                        "})()"

2- onPageFinished add:

view.evaluateJavascript(getFromPage) { 
                        Log.d("WebView", "Data: $value")}
Darwinism answered 6/6, 2023 at 15:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.