Solved

Replace function calls in external javascript file from WebView android

Posted on 2012-04-03
1
788 Views
Last Modified: 2012-06-22
An android app I'm working on relies on a web page for most of its functionality. When a user clicks a link that would normally call window.open I would like it to instead call a custom function. That way it stops the app from opening a browser window, which destroys the illusion of using an app. I already have a JavaScriptInterface set up to replace all the instances of window.open it finds in the page. The issue I'm having now is the external javascript file. It has a function very similar to this one

function LoadItem(url,title)
{
    window.open("/items.html?item=" + url + "&title=" + EncodeString(title), "song: " + title);
}

Open in new window


I would like to fix it up so it is this instead:

function LoadItem(url,title)
{
    window.LinkFixer.openInNewTab("/items.html?item=" + url + "&title=" + EncodeString(title), "song: " + title);
}

Open in new window


This is the code I have thus far that **should** be doing this for me.

public String processPage(String html)//called once the page has been loaded
{
    html = html.replace("window.open","window.LinkFixer.openInNewTab").replace("OpenSong","window.LinkFixer.openSong");
    String[] lines = html.split("\n");
    html = "";
    for(int i=0;i<lines.length;i++)
    {
        if(lines[i].contains("<script")&&lines[i].contains("src="))
        {
            lines[i] = getJs(lines[i]);
        }
        html += lines[i];
    }
    return html;
}

private String getJs(String line)//gets the javascript, fixes it so it's safe for the app, then returns it as inline rather than embeded
    {
        String jsFileName = line.replace("\"","'").replace("<script type='text/javascript' ","").replace("src=","").replace(">","").replace("'","").trim();
        //public static String makeGetRequest(String url,boolean oneLine)
        System.out.println(jsFileName);
        String targetUrl = "/BrowserControl/"+jsFileName;
        System.out.println(targetUrl);
        String jsFile = ShowWebInterface.makeGetRequest(targetUrl,false);
        Log.d("OrigFile"+jsFileName,jsFile);
        jsFile = jsFile.replace("window.open","window.LinkFixer.openInNewTab").replace("OpenSong","window.LinkFixer.openSong").replace("function window.LinkFixer.openSong(url, title)","window.LinkFixer.openSong");
        Log.d("NewFile"+jsFileName,jsFile);
        return "<script type=\"text/javascript\">\n"+jsFile;
    }

Open in new window


For the first click, it works. For anything after that, it loads the page in a browser window outside of the control of my app. The page I'm having issues with does use ajax, so I'm fairly sure that is causing some kind of issue. I would think that the browser would still call the onProgressChanged method, but I could be wrong.

browser.setWebChromeClient(new WebChromeClient()
    {
        public void onProgressChanged(WebView webView, int newProgress)
        {
            super.onProgressChanged(webView,newProgress);
            if(newProgress >= 100)
            {
                System.out.println("Done loading");
                browser.loadUrl("javascript:document.getElementsByTagName(\"html\")[0].innerHTML = window.LinkFixer.processPage((document.getElementsByTagName(\"html\")[0].innerHTML))");
            }
        }
    });

Open in new window


Is there something I'm missing? Some way to hijack the callback function of the ajax? Or maybe something else that I've overlooked.
0
Comment
Question by:HDM
1 Comment
 

Accepted Solution

by:
HDM earned 0 total points
ID: 37806853
I should have been using a normal WebViewClient for starters. Then I could have overridden the shouldOverrideUrlLoading method. Using that I was able to cut out all those large string replacements and everything works better than it did before.
0

Featured Post

ScreenConnect 6.0 Free Trial

At ScreenConnect, partner feedback doesn't fall on deaf ears. We collected partner suggestions off of their virtual wish list and transformed them into one game-changing release: ScreenConnect 6.0. Explore all of the extras and enhancements for yourself!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A short article about problems I had with the new location API and permissions in Marshmallow
You should read OS supplied guidelines before developing. I can't stress that enough. The guidelines will help you understand the reasons mobile app developers do what they do.  Apple is very particular when they review appstore submissions.
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question