0

I have set up a XAMPP server on a virtual machine, and I've set up a PHP code to return a very simple JSON object, the code is in android_connect/get_all_products

<?php

// array for JSON response
$response = array();
$response["name"] = "IPhone";

echo json_encode($response);
?>

And the code works, when I enter in my browser http://192.168.2.107/android_connect/get_all_products.php I get the correct JSON, even on an external machine on my network.

But I am unable to fetch it in an android application using Retrofit2.

below is a POJO I created to represent the JSON:

public class Results {

    @SerializedName("name")
    private String name;

    public Results(String pid, String name) {

        this.name = name;
    }

    public String getName() {
        return name;
    }
}

This is the API interface:

public interface Api {

    String BASE_URL = "http://192.168.2.107/";
    @GET("android_connect/get_all_products.php")
    Call<Results> displayName();
}

And this is the retrofit client instance:

public class RetrofitClient {

    private static RetrofitClient instance = null;
    private Api myApi;

    private RetrofitClient() {
        Retrofit retrofit = new Retrofit.Builder().baseUrl(Api.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        myApi = retrofit.create(Api.class);
    }

    public static synchronized RetrofitClient getInstance() {
        if (instance == null) {
            instance = new RetrofitClient();
        }
        return instance;
    }

    public Api getMyApi() {
        return myApi;
    }
}

and finaly this is the main activity code:

public class MainActivity extends AppCompatActivity {

    ListView superListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        superListView = findViewById(R.id.superListView);

        getSuperHeroes();
    }

    private void getSuperHeroes() {
        Call<Results> call = RetrofitClient.getInstance().getMyApi().displayName();
        call.enqueue(new Callback<Results>() {
            @Override
            public void onResponse(Call<Results> call, Response<Results> response) {
                Toast.makeText(getApplicationContext(), response.body().getName(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure(Call<Results> call, Throwable t) {
                Toast.makeText(getApplicationContext(), "An error has occured", Toast.LENGTH_LONG).show();
            }

        });
    }
}

Everytime I get a toast saying An error has occured (as it means the call has failed somewhere)

NOTES: I have added INTERNET permission in the manifest.xml file I have tried some variation of my code on an external server and it runs fine, seems like the problem happens when I try to connect to my server.

Thank you in advance, I am very new to android programing and I have an assignment to connect it to a php server.

EDIT: as ADyson pointed, the throwable t in onFailure, gives the folowing message: cLEARTEXT communication to 192.168.2.107 not permitted by network security policy. What does that mean? and what should I do?

  • you need to look at the error details provided to you in the onFailure call then, and see what the specific problem is. At the moment, your code just discards all that information and outputs a generic message, which is probably why you don't know what's going wrong. You need to log it somewhere. – ADyson Feb 23 '22 at 16:48
  • 1
    Having said that, `"http://192.168.2.107/"` is clearly a local LAN URL. So unless you're connecting from a device which is on the same LAN as the server, then obviously it will never connect because the NAT/firewall on the router will prevent it. – ADyson Feb 23 '22 at 16:48
  • yes, the device I am connection from is connected to the local network, in addition, how should I log the error messages in onFailure? – charbel karam Feb 23 '22 at 17:13
  • You can log them however you wish... the important point is to make sure you have access to the info, for debugging – ADyson Feb 23 '22 at 17:13
  • Probably android network security policy is blocking a plain text http connection. Check this https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted – Bimalesh Jha Feb 23 '22 at 17:34

1 Answers1

1

Resolved: android network security blocks HTTP request by default, to enable it add to Manifest.xml:

android:usesCleartextTraffic="true"