[java] Http Get using Android HttpURLConnection

I'm new to Java and Android development and try to create a simple app which should contact a web server and add some data to a database using a http get.

When I do the call using the web browser in my computer it works just fine. However, when I do the call running the app in the Android emulator no data is added.

I have added Internet permission to the app's manifest. Logcat does not report any problems.

Can anyone help me to figure out what's wrong?

Here is the source code:

package com.example.httptest;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class HttpTestActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView tv = new TextView(this);
        setContentView(tv);

        try {
            URL url = new URL("http://www.mysite.se/index.asp?data=99");
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.disconnect();
            tv.setText("Hello!");
        }
        catch (MalformedURLException ex) {
            Log.e("httptest",Log.getStackTraceString(ex)); 
        }
        catch (IOException ex) {
            Log.e("httptest",Log.getStackTraceString(ex));
        }   
    }        
}

This question is related to java android-emulator android-internet

The answer is


I have created with callBack(delegate) response to Activity class.

public class WebService extends AsyncTask<String, Void, String> {

    private Context mContext;
    private OnTaskDoneListener onTaskDoneListener;
    private String urlStr = "";

    public WebService(Context context, String url, OnTaskDoneListener onTaskDoneListener) {
        this.mContext = context;
        this.urlStr = url;
        this.onTaskDoneListener = onTaskDoneListener;
    }

    @Override
    protected String doInBackground(String... params) {
        try {

            URL mUrl = new URL(urlStr);
            HttpURLConnection httpConnection = (HttpURLConnection) mUrl.openConnection();
            httpConnection.setRequestMethod("GET");
            httpConnection.setRequestProperty("Content-length", "0");
            httpConnection.setUseCaches(false);
            httpConnection.setAllowUserInteraction(false);
            httpConnection.setConnectTimeout(100000);
            httpConnection.setReadTimeout(100000);

            httpConnection.connect();

            int responseCode = httpConnection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(new InputStreamReader(httpConnection.getInputStream()));
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                br.close();
                return sb.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        if (onTaskDoneListener != null && s != null) {
            onTaskDoneListener.onTaskDone(s);
        } else
            onTaskDoneListener.onError();
    }
}

where

public interface OnTaskDoneListener {
    void onTaskDone(String responseData);

    void onError();
}

You can modify according to your needs. It's for get


URL url = new URL("https://www.google.com");

//if you are using

URLConnection conn =url.openConnection();

//change it to

HttpURLConnection conn =(HttpURLConnection )url.openConnection();


If you just need a very simple call, you can use URL directly:

import java.net.URL;

    new URL("http://wheredatapp.com").openStream();

Here is a complete AsyncTask class

public class GetMethodDemo extends AsyncTask<String , Void ,String> {
    String server_response;

    @Override
    protected String doInBackground(String... strings) {

        URL url;
        HttpURLConnection urlConnection = null;

        try {
            url = new URL(strings[0]);
            urlConnection = (HttpURLConnection) url.openConnection();

            int responseCode = urlConnection.getResponseCode();

            if(responseCode == HttpURLConnection.HTTP_OK){
                server_response = readStream(urlConnection.getInputStream());
                Log.v("CatalogClient", server_response);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        Log.e("Response", "" + server_response);


    }
}

// Converting InputStream to String

private String readStream(InputStream in) {
        BufferedReader reader = null;
        StringBuffer response = new StringBuffer();
        try {
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return response.toString();
    }

To Call this AsyncTask class

new GetMethodDemo().execute("your web-service url");

A more contemporary way of doing it on a separate thread using Tasks and Kotlin

private val mExecutor: Executor = Executors.newSingleThreadExecutor()

private fun createHttpTask(u:String): Task<String> {
    return Tasks.call(mExecutor, Callable<String>{
        val url = URL(u)
        val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
        conn.requestMethod = "GET"
        conn.connectTimeout = 3000
        conn.readTimeout = 3000
        val rc = conn.responseCode
        if ( rc != HttpURLConnection.HTTP_OK) {
            throw java.lang.Exception("Error: ${rc}")
        }
        val inp: InputStream = BufferedInputStream(conn.inputStream)
        val resp: String = inp.bufferedReader(UTF_8).use{ it.readText() }
        return@Callable resp
    })
}

and now you can use it like below in many places:

            createHttpTask("https://google.com")
                    .addOnSuccessListener {
                        Log.d("HTTP", "Response: ${it}") // 'it' is a response string here
                    }
                    .addOnFailureListener {
                        Log.d("HTTP", "Error: ${it.message}") // 'it' is an Exception object here
                    }

Simple and Efficient Solution : use Volley

 StringRequest stringRequest = new StringRequest(Request.Method.GET, finalUrl ,
           new Response.Listener<String>() {
                    @Override
                    public void onResponse(String){
                        try {
                            JSONObject jsonObject = new JSONObject(response);
                            HashMap<String, Object> responseHashMap = new HashMap<>(Utility.toMap(jsonObject)) ;
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d("api", error.getMessage().toString());
            }
        });

        RequestQueue queue = Volley.newRequestQueue(context) ;
        queue.add(stringRequest) ;