9
votes

I have a mobile web application built using the following versions :-

  1. JQuery Mobile : Alpha 4 v1.0a4.1
  2. JQuery: v1.6.1
  3. PhoneGap : v0.9.5

Using phonegap, this application is built into a native android application and deployed.

In my application, i make various AJAX calls using $.ajax to external websites. For this i employ dataType: 'jsonp' inorder to do the cross domain calling.

When i was testing my app in Chrome v12.0.742.100, everything was working fine and I had no issues with retrieving the data from the external sites. However, as soon as i packaged this into a .apk file and try to run this in the emulator, i find that none of the ajax calls are working.

I have put alerts before and after the ajax call and verified that both alerts are called but the ajax call is as good as ignored. I have logging in both the success callback and the error callback and neither is being reached. I have also verified by puting a breakpoint on the external server website (for my testing, i am just having a separate website on my local machine itself) and the server page is definitely not being called.

In logcat, the error that i can see is this : D/SntpClient( 59): request time failed: java.net.SocketException: Address family not supported by protocol

I am pretty new to phonegap as well as Jquery Mobile but as far as my understanding goes, my phonegap app file is referenced by file:/// protocol whereas my AJAX URL is http://127.0.0.1:someport/someapp/somepage and the error seems to be indicating that these two dont mix!! If this is indeed the case, how do i go about make ajax calls from a phonegap deployed application?

Please feel free to point out anything else that may be helpful! I am pretty stumped at this point.

Edit : I have checked the AndroidManifest.xml file and all the permissions as per this phonegap wiki link are set in this file.

Edit 2 : Adding in my client side code that intitiates the ajax call

var serverUrl = "http://localhost:2424/MyServer/RetrieveMasterData.aspx";
            $.ajax({
                url: serverUrl,
                type: 'POST',
                dataType: 'jsonp',
                data: { MasterDataID: 1 },
                success: function(response) {
                        ...... business logic here
                },
                error: function(xhr, ajaxOptions, thrownError) {
                        ...... error handling something here
                }
            });
3
Hi, have you added the permission for connecting to the Internet?Francisc
I've no idea why it works on your chrome but not on ur android. But 1 thing i know for sure is that the same origin policy doesn't apply to file:/// protocol.root
Can you post a code snippet that shows the issue.Paul Beusterien
@Paul - Updated the question with a code snippet of one of the ajax callsJagmag
I am facing with the same problem on Android 2.2 but in Android 2.3 it works fine.Cas Sakal

3 Answers

11
votes

Android emulator does not recognize "localhost"...it should be 10.0.2.2 instead. try changing the url to http://10.0.2.2:2424/MyServer/RetrieveMasterData.aspx

2
votes

Because the request is not in the same domain, and I solved the problem by adding jqm config that:

$( document ).bind( "mobileinit", function() {
  // Make your jQuery Mobile framework configuration changes here!

  $.mobile.allowCrossDomainPages = true;
});

And this is a link: http://jquerymobile.com/demos/1.0/docs/pages/phonegap.html

0
votes

Another issue which occurs in Android 4.0+ (but not in older versions like 2.3)... is for ajax calls that require Basic Auth. You have to manually set the Authorization header in beforeSend. You cannot use the new username: password: options added in jQuery 1.7.

The example below illustrates what you have to do. Note: This requires the base64 jquery plugin.

 $.ajax({
            url: "https://yoururl,
            type: method,
            dataType: 'json',
            // username: username,  // Doesn't work on ANDROID
            // password: password,  // Doesn't work on ANDROID
            beforeSend: function (xhr)
            {
                xhr.setRequestHeader("Authorization", "Basic " + $.base64.encode( username + ":" + password ));
            },
            data: options.data,
            success: function(response) {

            },
            error: function(jqXHR, textStatus, errorThrown) {

            }
        });