Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Replace function calls in external javascript file from WebView android

Posted on 2012-04-03
1
Medium Priority
?
804 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Build and deliver software with DevOps

A digital transformation requires faster time to market, shorter software development lifecycles, and the ability to adapt rapidly to changing customer demands. DevOps provides the solution.

Question has a verified solution.

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

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.
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
This video demonstrates how to sync Microsoft Exchange Public Folders with smartphones using CodeTwo Exchange Sync and Exchange ActiveSync. To learn more about CodeTwo Exchange Sync and download the free trial, go to: http://www.codetwo.com/excha…
Suggested Courses

721 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