Solved

Replace function calls in external javascript file from WebView android

Posted on 2012-04-03
1
786 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Android studio getdrawable(int) is deprecated 4 39
DGTEC 10.1" Quad Core Android Tablet 18 95
Old GPS chip on Samsung Tab 4 - Kit Kat? 2 35
javap not working 8 36
Often, people trade privacy and security for convenience. However in today's concrete jungle, this is an extremely foolish decision considering the vast amount of technologies being used against consumer interest. First off, I won't waste any time e…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
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 …

910 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now