Android emulator networking epic fail

I’ve built an app with ionic v1.0.0-beta.14 and it works fantastic in a Chrome browser and using the iOS emulator. I did have to fix CORS settings on my server (setup express-cors).

In my AndroidManifest.xml I have this:

<uses-permission android:name="android.permission.INTERNET" />

In the Cordova config.xml I have this:

<access origin="*"/>

I am using Angular’s $resource, this is what happens when I issue a request, example code:

angular.module('app').
  .factory('Foo', ['$resource', 'serviceConfig', function ($resource, serviceConfig) {
    return $resource(serviceConfig.url + '/api/foo');
  }])
  .controller('FooCtrl', ['$scope', 'Foo', function ($scope, Foo) {
    Foo.query();
  }])

I have an Angular interceptor for both request and response errors:

 $httpProvider.interceptors.push(['$q', '$log', function ($q, $log) {

      return {
        
        requestError: function (rejection) {
          $log.error('request error interceptor => ', JSON.stringify(rejection, null, 2));
          return $q.reject(rejection);
        },

        responseError: function (rejection) {
          $log.error('response error interceptor => ', JSON.stringify(rejection, null, 2));
          $rootScope.$broadcast('response:error', rejection);
          return $q.reject(rejection);
        }
      };
    }]);

Here’s what the client side logs when the request is attempted by the controller + service:

2     866095   error    response error interceptor => , {
  "data": null,
  "status": 0,
  "config": {
    "method": "POST",
    "transformRequest": [
      null
    ],
    "transformResponse": [
      null
    ],
    "data": {
      "email": "foo@bar.com",
      "password": "foobar"
    },
    "url": "http://localhost:3000/api/foo",
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "application/json;charset=utf-8"
    }
  },
  "statusText": ""
}

The webserver is also running on http://localhost:3000. Again, the Ionic app running in Chrome or iOS simulator work fine with this setup.

So, I fire up tcpdump to take a look and see what the Android emulator is actually sending out:

$ sudo tcpdump -i lo0 -s 0 -A port 3000

…and it turns out it is a big pile of nothing. No packets are captured. Again, if I fire the app up in Chrome or the iOS simulator all the traffic is captured in tcpdump.

So something – some additional permission, or setting seems to be prohibiting my app from making AJAX requests from Android’d WebView. I would appreciate any additional pointers here.

The only other thing I can think of is this API setAllowUniversalAccessFromFileURLs perhaps needs to be set, but that has to be set on the WebView itself, and I’m not sure I have access to the particular web view that is launched in the Ionic app - have to go dig into the source now.

Simple follow up, I tried vanilla JS XHR and it also fails, so this takes Angular out of the picture.

My guess is that you need to refer to the real IP address of the machine and not local host in your JavaScript. android has a reserved address for the emulator that maps to local host on the same machine -10.0.2.2 you can use to test

1 Like

Thanks @waterishail – good call. I did swap it out for the IP address, and it resolves the issue.