MH16
MH16

Reputation: 2356

URL with parameter in WebView not working in Android?

I am trying to call the loadUrl method in a webview with the below url

http://stage.realtylog.net/iPhone/functions.php?username=xxx&ID=xxx&act=readFileAndPrint

When calling this URL, it gives an image from server. I need to display that image on a webview.

It's working fine with normal URLs. But its not working with the above url with parameters.

It gives me an error like:

Function name must be a string in /var/www/stage/realtylog.net/iPhone/functions.php

I tried to URLEncode the above url , but its still not working. Any kind of help will be highly appreciated.

package com.hussain.webview2;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.webkit.SslErrorHandler;
import android.net.http.*;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;


public class WebViewDemo2Activity extends Activity
{
   final Activity activity = this;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
       super.onCreate(savedInstanceState);
       this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
       setContentView(R.layout.main);

       WebView webView = (WebView) findViewById(R.id.webview);
      // webView.setWebViewClient(new WebViewClient());
      // webView.addView(webView.getZoomControls());
      webView.getSettings().setJavaScriptEnabled(true);

      webView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress)
        {
            activity.setTitle("Loading...");
            activity.setProgress(progress * 100);

            if(progress == 100)
                activity.setTitle("Done");
        }
    });

    webView.setWebViewClient(new WebViewClient() {
        @Override
       public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
       {
           // Handle the error
       }



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

    //webView.loadUrl("http://developer.android.com");
    webView.loadUrl("http://stage.realtylog.net/iPhone/functions.php?username=xxxx&ID=xxxx&act=readFileAndPrint");


    }
}

Upvotes: 12

Views: 33712

Answers (8)

Istiak Morsalin
Istiak Morsalin

Reputation: 11149

This fixes the issue:

webView.getSettings().setDomStorageEnabled(true);

Upvotes: 3

ji chen
ji chen

Reputation: 11

change your url to:

webView.loadUrl(MessageFormat.format("{0}{1}{2}","http://stage.realtylog.net/iPhone/functions.php",URLEncoder.encode("?username=xxxx"),URLEncoder.encode("&ID=xxxx"),URLEncoder.encode("&act=readFileAndPrint")));

js file like this:

data= JSON.parse(decodeURIComponent(data));

Upvotes: 1

jeet
jeet

Reputation: 29199

change your url to:

StringBuffer buffer=new StringBuffer("http://stage.realtylog.net/iPhone/functions.php");
buffer.append("?username="+URLEncoder.encode("xxxxxxx"));
buffer.append("&id="+URLEncoder.encode("xxxxxxxx"));
buffer.append("act="+URLEncoder.encode("readFileAndPrint"));
webView.loadUrl(buffer.toString());

Upvotes: 7

Joao B
Joao B

Reputation: 101

As Dino Fancellu pointed out, its a bad bug, but I think it only applies to the asset local files in your android project.
Incredibly enough, this bug did not exist in versions 2+ (Froyo).
And my app relied heavily on passing url variables to /asset/ files.
I was only passing one variable (?id=xx), but heres how i fixed it, and tweaked it to work with multiple variables:

    // in App declare a string to hold the url parameters
    String strUrlParams;

    // In WebViewClient, Override the onReceiveError
    // Basially check if params exist in Url, strip them and save them to string
    private class HelloWebViewClient extends WebViewClient {
    @Override
    public void onReceivedError(WebView webview, int errorCode, String description, String failingUrl)
    {
        System.out.println("onReceivedError: " + description);
        if (failingUrl.contains("?")) {
                String[] temp;
                temp = failingUrl.split(Pattern.quote("?"));
                strUrlParams = temp[1]; // save params to string
                webview.loadUrl(temp[0]); // load page without params

        } else {
        webview.loadUrl("file:///android_asset/error.html");
        }
    }
    ..........
    }


    // In JavascriptInterface, add method to return the params string
    public String getUrlPString() {
    return strUrlParams;
    }


    // In the webpage that is expecting the params, add javascript to grab them.
    var getUrlParam = function(theParam) {
    var strParam = "nada";
    var query = window.location.search.substring(1);
    if(query.indexOf("=") != -1)  { // check if params
    ....
    } else { 
    // no params in url, grab params string from app
    query = app.getUrlPString();
    }
    var vars = query.split("&");
    for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    if (pair[0] == theParam) {
    strParam = pair[1];
    }
    }
    return strParam;
    }

    // example to grab the ?id=xx param 
    var theID = getUrlParam("id");
  • But as per this pages question, its not a local asset file; is a http:// url. From what I understand, WebView is not throwing the error. Your php script is: "Function name must be a string in /var/www/stage/realtylog.net/iPhone/functions.php"
    This may be usefull:
    PHP Fatal error: Function name must be a string

Upvotes: 0

Elyess Abouda
Elyess Abouda

Reputation: 659

I searched a lot to solve this issue but found nothing working. Though I only encountered this problem with android < 4.0

I only encountered this problem when first loading the url. If the webview has already loaded some other url it works fine.

So this is my workaround that works although it is really silly.

        if (API_ICS_OR_LATER) {

            mWebView.loadUrl(mURL);


        } else {
            /***
             * Workaround for Webview bug when url contains parameters
             * https://code.google.com/p/android/issues/detail?id=17535
             */

            mWebView.loadData("<html></html>", "text/html", "UTF-8");

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    mWebView.loadUrl(mURL);

                }
            }, 500);
        }

Upvotes: 2

bboydflo
bboydflo

Reputation: 947

I managed to pass variables in a different way.

My problem was that anytime I switched to another app, when coming to the webapp, the webview kept reloading. I guess that's because of the following line in my onCreate() method: myWebView.loadUrl(url); I had the idea to pass these state variables in the url, but as you know it is not possible yet. What I did was to save the state of some variables using onSaveInstanceState(Bundle outState) {...} and restore them with onRestoreInstanceState(Bundle savedInstanceState){...}.

In onCreate method after setting up myWebView I did the following:

myWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String urlString)
{
     Log.i("onPageFinished", "loadVariables("+newURL+")");
     if(newURL!="")
         myWebView.loadUrl("javascript:loadVariables("+"\""+newURL+"\")");
}

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

jsInterface = new JSInterface(this,myWebView);
myWebView.addJavascriptInterface(jsInterface, "Android");

if (savedInstanceState != null)
{
// retrieve saved variables and build a new URL
newURL = "www.yoururl.com";
newURL +="?var1=" + savedInstanceState.getInt("key1");
newURL +="?var2=" + savedInstanceState.getInt("key2");
Log.i("myWebApp","NEW URL = " + newURL);
}
myWebView.loadUrl("www.yoururl.com");

So, what it happens is that first I load the page and then I pass the variables when the page finished to load. In javascript loadVariables function looks like this:

function loadVariables(urlString){
    // if it is not the default URL
    if(urlString!="www.yoururl.com")
    {
        console.log("loadVariables: " + urlString);
        // parse the URL using a javascript url parser (here I use purl.js)
        var source = $.url(urlString).attr('source');
        var query = $.url(urlString).attr('query');  
        console.log("URL SOURCE = "+source + " URL QUERY = "+query);
        //do something with the variables 
    }
}

Upvotes: 0

Dino Fancellu
Dino Fancellu

Reputation: 2004

Welcome to a horrible known bug, that Google doesn't feel like fixing, or even addressing.

http://code.google.com/p/android/issues/detail?id=17535

Upvotes: 17

Chirag_CID
Chirag_CID

Reputation: 2224

Yoy can use a List of NameValuePair and URLEncodedUtils to create the url string..

protected String addLocationToUrl(String url){
    if(!url.endsWith("?"))
        url += "?";

    List<NameValuePair> params = new LinkedList<NameValuePair>();

    if (lat != 0.0 && lon != 0.0){
        params.add(new BasicNameValuePair("lat", String.valueOf(lat)));
        params.add(new BasicNameValuePair("lon", String.valueOf(lon)));
    }

    if (address != null && address.getPostalCode() != null)
        params.add(new BasicNameValuePair("postalCode", address.getPostalCode()));
    if (address != null && address.getCountryCode() != null)
        params.add(new BasicNameValuePair("country",address.getCountryCode()));

    params.add(new BasicNameValuePair("user", agent.uniqueId));

    String paramString = URLEncodedUtils.format(params, "utf-8");

    url += paramString;
    return url;
}

Alternate option is like following...you can try this also...

HttpPost postMethod = new HttpPost("your url");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();

nameValuePairs.add(new BasicNameValuePair("your parameter","parameter value"));
nameValuePairs.add(new BasicNameValuePair("your parameter","parameter value"));

postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
DefaultHttpClient hc = new DefaultHttpClient();

HttpResponse response = hc.execute(postMethod);

Upvotes: 0

Related Questions