0

So I am developing an Android application that has to interact with an API I coded. For now I just run the API locally. I have tested all the routes already and they all work.

Now I would like to send requests to this API on my Android application. For that I use a class RequestManager that extends AsyncTask to manage each request (I can show you the code if you ask). I have added <uses-permission android:name="android.permission.INTERNET" /> and <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> in the Manifest.

When I execute a request throught the RequestManager using the IP address of my PC, it pauses for some time then throws a SocketTimeoutException with the following error: failed to connect to /XX.XX.XX.XX (port XXXX) from /XX.XX.XX.XX (port XXXX). Note that making the same request from Postman works without issue.

So I tried multiple things like adding a file network_security_config.xml to permit the traffic with the IP address of my PC, I deactivated my firewall, I added several inbound and outbound rules on my firewall to give permissions to Android Studio, the IP address, the used port etc.. but nothing seems to fix the issue..

Has anyone experienced the same or can anyone help me fix this ? I really need to get it working..

EDIT: Here is the RequestManager class:

class RequestManager extends AsyncTask<HashMap<String, Object>, Void, Response> {

    protected Response doInBackground(HashMap<String, Object>... parameterMaps) {
        Response response = null;
        HashMap<String, Object> params = parameterMaps[0];
        String method = (String) params.get("method");
        if ("GET".equals(method)) {
            response = doGet(params);
        } else if ("POST".equals(method)) {
            response = doPost(params);
        } else if ("UPDATE".equals(method)) {
            response = doUpdate(params);
        } else if ("DELETE".equals(method)) {
            response = doDelete(params);
        }
        return response;
    }

    private Response doGet(HashMap<String, Object> params) {
        Response response = null;
        try {
            OkHttpClient client = new OkHttpClient();

            Context context = (Context) params.get("context");
            String protocol = Config.getConfigValue(context, "protocol");
            String ipAddress = Config.getConfigValue(context, "ipAddress");
            String port = Config.getConfigValue(context, "port");
            String route = (String) params.get("route");
            String url = protocol + ipAddress + ":" + port + "/" + route;

            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Cache-Control", "no-cache")
                    .build();

            response = client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    private Response doPost(HashMap<String, Object> params) {
        Response response = null;
        try {
            OkHttpClient client = new OkHttpClient();

            Context context = (Context) params.get("context");
            String protocol = Config.getConfigValue(context, "protocol");
            String ipAddress = Config.getConfigValue(context, "ipAddress");
            String port = Config.getConfigValue(context, "port");
            String route = (String) params.get("route");
            String url = protocol + ipAddress + ":" + port + "/" + route;

            MediaType mediaType = MediaType.parse("application/json");
            String bodyContent = params.get("body").toString();
            RequestBody body = RequestBody.create(mediaType, bodyContent);

            Request request = new Request.Builder()
                    .url(url)
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Cache-Control", "no-cache")
                    .build();

            response = client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    private Response doUpdate(HashMap<String, Object> params) {
        Response response = null;
        try {
            OkHttpClient client = new OkHttpClient();

            Context context = (Context) params.get("context");
            String protocol = Config.getConfigValue(context, "protocol");
            String ipAddress = Config.getConfigValue(context, "ipAddress");
            String port = Config.getConfigValue(context, "port");
            String route = (String) params.get("route");
            String url = protocol + ipAddress + ":" + port + "/" + route;

            MediaType mediaType = MediaType.parse("application/json");
            String bodyContent = params.get("body").toString();
            RequestBody body = RequestBody.create(mediaType, bodyContent);

            Request request = new Request.Builder()
                    .url(url)
                    .put(body)
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Cache-Control", "no-cache")
                    .build();

            response = client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    private Response doDelete(HashMap<String, Object> params) {
        Response response = null;
        try {
            OkHttpClient client = new OkHttpClient();

            Context context = (Context) params.get("context");
            String protocol = Config.getConfigValue(context, "protocol");
            String ipAddress = Config.getConfigValue(context, "ipAddress");
            String port = Config.getConfigValue(context, "port");
            String route = (String) params.get("route");
            String url = protocol + ipAddress + ":" + port + "/" + route;

            Request request = new Request.Builder()
                    .url(url)
                    .delete()
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Cache-Control", "no-cache")
                    .build();

            response = client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    protected void onPostExecute(Response response) {

    }
}

And here's how I call it:

        HashMap<String, Object> params = new HashMap<>();
        JSONObject body = Utils.jsonify(content);
        params.put("body", body);
        params.put("route", Constants.User.BASE_USER);
        params.put("context", SignUp.this);
        params.put("method", "POST");

AsyncTask<HashMap<String, Object>, Void, Response> requestManager = new RequestManager().execute(params);
  • Post your AsyncTask class – L2_Paver Oct 11 '19 at 09:51
  • 2
    you API and postman are on the same machine and that's why working flawlessly. but, you machine is not accessible from your phone directly, so, your phone can't reach to your API. You can use an emulator on your machine, that might ease the workflow, but are some ways to reach local machine from your phone over wifi, you can check this post https://stackoverflow.com/questions/51889837/cannot-connect-to-localhost-api-from-android-app – touhid udoy Oct 11 '19 at 09:52
  • @TouhidulIslam I am using the IP address of my machine as recommended, not localhost or 127.0.0.1 but it still doesn't work. – Daniel Baptista Oct 11 '19 at 10:01
  • @L2_Paver I have edited my post – Daniel Baptista Oct 11 '19 at 10:03
  • What ip is you api listening on? (localhost? wildcard address? wifi intranet ip? – Juan Oct 11 '19 at 10:16
  • I'm sorry I didn't understand your question @Juan – Daniel Baptista Oct 11 '19 at 10:20
  • are you using apache server on your machine? if yes, by default all the local traffic is (not the loopback) are defined to deny request. You need to change in httpd.config or some file like that – Rahul Oct 11 '19 at 10:26
  • Your backend, apache, tomcat, whatever you are using is listening on some address and port. Check which address it is listening on. If it is bound to localhost only you need to change it to the intranet ip or to the wildcard address which listens on all interfaces. – Juan Oct 11 '19 at 10:32

1 Answers1

1

use localtunnel to expose your local api temporarily. This works like a charm and is very easy to use. have used it for multiple projects to test against local API.

Joachim Haglund
  • 775
  • 5
  • 15