Http Get using Android HttpURLConnection
Asked Answered
G

7

71

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));
        }   
    }        
}
Gifferd answered 28/12, 2011 at 10:47 Comment(0)
V
80

Try getting the input stream from this you can then get the text data as so:-

    URL url;
    HttpURLConnection urlConnection = null;
    try {
        url = new URL("http://www.mysite.se/index.asp?data=99");

        urlConnection = (HttpURLConnection) url
                .openConnection();

        InputStream in = urlConnection.getInputStream();

        InputStreamReader isw = new InputStreamReader(in);

        int data = isw.read();
        while (data != -1) {
            char current = (char) data;
            data = isw.read();
            System.out.print(current);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }    
    }

You can probably use other inputstream readers such as buffered reader also.

The problem is that when you open the connection - it does not 'pull' any data.

Volsung answered 28/12, 2011 at 11:3 Comment(4)
You should close your connection in a finally blockReceipt
I deliberately used broad exceptions to keep method from becoming too verbose. Users should try and use more specific ones where appropriate.Volsung
I can't find what exception is thrown by disconnect?Matthus
Yeah, try catch is unneeded for disconnect(), have removed.Volsung
O
45

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");
Obscene answered 11/7, 2016 at 18:3 Comment(0)
T
19

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

Telescopy answered 31/8, 2016 at 6:33 Comment(4)
This is very helpful. I do have a couple of questions though. The variable mContext is assigned by never referenced. Does it need to be there? Also, does the connection need to be disconnected as commented above?Iceni
If you don't need it then remove it. but most of the time I need activity context in AsyncTask. And the second point are you taking about setConnectTimeout . If there is a delay in response more then 10 sec. You face an ANdrod NOt Responding message.Telescopy
I'm new to this environment so trying to understand best practices. @Luigi commented to Davos555: "You should close your connection in a finally block". I see that you have a br.close() to close the reader, but should there also be an httpConnection.disconnect() somewhere, or does it matter?Iceni
Yes @John Ward you are right the connection should also be closed.Telescopy
W
4

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

import java.net.URL;

    new URL("http://wheredatapp.com").openStream();
Western answered 19/9, 2015 at 16:27 Comment(0)
A
1

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) ;
Ambidextrous answered 1/7, 2018 at 7:32 Comment(0)
L
0

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
                    }
Liechtenstein answered 21/11, 2020 at 5:36 Comment(0)
M
-5

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

//if you are using

URLConnection conn =url.openConnection();

//change it to

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

Model answered 2/11, 2016 at 8:6 Comment(1)
He's using HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();.Directional

© 2022 - 2024 — McMap. All rights reserved.