4

Hi I have this activity code:

public class WebActivity extends ActionBarActivity {

    TextView number;

    WebView mWebView;
    CountDownTimer mTimer;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);


        number = (TextView) findViewById(R.id.number);
        mTimer=new CountDownTimer(10000, 1000) {
            String[] myArray={"javascript:document.getElementById(\"utente\").value=\""+LoginActivity.username+"\"; document.getElementById(\"j_password\").value=\""+LoginActivity.password+"\"; document.querySelector(\"input[type=submit]\").click();","javascript:document.getElementById(\"menu-servizialunno:_idJsp14\").click();"};


            int currentIndex=0;
            public void onTick(long millisUntilFinished) {

                number.setText("seconds remaining: " + millisUntilFinished / 1000 + " " + (currentIndex + 1) + "/" + (myArray.length + 1));
            }
            //code comment start
            // i think this part could be written better
            // but it works!!
            public void onFinish() {
                if (currentIndex<myArray.length) {
                    number.setText("done!");
                    mWebView.loadUrl(myArray[currentIndex]);
                    currentIndex++;
                    mTimer.start();
                } else{
                    mTimer.cancel();

                }

            }
            //code comment end
        };

        mTimer.start();
        mWebView = (WebView) findViewById(R.id.webview);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setWebViewClient(new WebSliderWebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(mWebView, url);
                Toast.makeText(getApplicationContext(), "Done!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Toast.makeText(getApplicationContext(), "Oh no! " + description, Toast.LENGTH_SHORT).show();

            }
        });
        mWebView.loadUrl("http://www.ss16374.scuolanext.info");



    }

and this js function:

function voti( showSubject, showData, showVote ){
    var votitotali = []
    document.getElementById("menu-servizialunno:_idJsp14").click();
    setTimeout(function(){
        elems = document.querySelectorAll("td, legend");
        for(var i = 0; i < elems.length; i++){
            curText = elems[i].innerHTML;
            if( elems[i].tagName == "LEGEND" && showSubject ){
                votitotali += [curText]
                //console.log( curText );
            }else if( elems[i].innerHTML.indexOf("Voto") != -1 && showVote ){
                votitotali += [curText.replace(/.*\(([0-9\.]+)\)/,"$1")]
                //console.log( curText.replace(/.*\(([0-9\.]+)\)/,"$1") );
            }else if( /\d{2}\/\d{2}\/\d{4}/.test(elems[i].innerHTML) && showData ){
                votitotali += [curText.replace(/.*(\d{2}\/\d{2}\/\d{4}).*/,"$1")]
                //console.log( curText.replace(/.*(\d{2}\/\d{2}\/\d{4}).*/,"$1") );
            }
        }
        document.getElementsByClassName("btl-modal-closeButton")[0].click()
    },3000);
    return votitotali
}

Can I store the votitotali array in my android app? Because I need to get some informations from a site and I have to print them on a textView in the app, but I really do not know how to do this using webview...

Alessio Ragno
  • 476
  • 1
  • 6
  • 20
  • but... I can't use that, because I need to implement that function with the webview, the function has to get the informations using android webview – Alessio Ragno Jul 06 '15 at 23:19

1 Answers1

5

That's actually easy. You need to inject a Java object which has a method receiving an array:

class MyReceiver {
    @JavascriptInterface
    public void receive(String[] input) {
        // input is your data!
    }
}

// At the very beginning
mWebView.addJavascriptInterface(new MyReceiver(), "receiver");
// ...

Then if you call it like that in your JavaScript code:

receiver.receive(voti( ... ));

You will get the array inside MyReceiver.receive.

Note that non-string array elements (e.g. numbers) will not be converted into strings, and will be replaced by nulls instead.

Mikhail Naganov
  • 6,643
  • 1
  • 26
  • 26
  • So I just have to type mwevview.loadUrl("javascript:voti(showSubject, showData, showVote){...}"); and then call receiver.receiver(voti(1, 1, 1));?? – Alessio Ragno Jul 07 '15 at 09:17
  • This is what I did, I called the javascript function in mTimer... http://alessio.ragno.info/android.txt – Alessio Ragno Jul 07 '15 at 09:44
  • `mWebView.loadUrl("receiver.receive(voti(1,1,1));");` should become `mWebView.loadUrl("javascript:receiver.receive(voti(1,1,1));");` – Mikhail Naganov Jul 07 '15 at 16:53
  • How can I use the input array out of that class/function? I tried making it a global variable but it doesn't work... If it is possible I need to use that also in another activity... – Alessio Ragno Jul 07 '15 at 17:32
  • Be aware that the code of injected methods runs on a different thread (see WebView.html.addJavascriptInterface [docs](http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String))), so you will need to use synchronization if you intend to make it a global variable. Also, see this question for a possible way of sharing data across activities: http://stackoverflow.com/questions/1944656/android-global-variable – Mikhail Naganov Jul 07 '15 at 20:14
  • I edited the receive function and i added two more arrays... these are big... And I get this error: `JNI ERROR (app bug): local reference table overflow (max=512)` How can I fix it? – Alessio Ragno Jul 16 '15 at 18:31
  • Probably, reduce the amount of information passed. Looks like when converting your data from JS to Java, the amount of temporary Java objects created exceeds Java VM capabilities. – Mikhail Naganov Jul 16 '15 at 21:20