I am trying to learn how to connect to an API and receieve and parse JSON data so I am currently following an example on this webpage: http://www.whycouch.com/2012/12/how-to-create-android-client-for-reddit.html, but I am getting an error that says:
E/fetchPosts(): org.json.JSONException: End of input at character 0 of
My app is connecting because it says that a new host connection has been established so I'm not quite sure as to why it's getting a blank response. Below is my class that gets the connection and reads the contents. If I had to guess where I went wrong, I would say it has to do with the request properties, but I went to reddit's website and formatted it like they want and it's still not returning anything. Thank you.
public class RemoteData {
/*
This method returns a connection to the specified URL,
with necessary properties like timeout and user-agent
set to your requirements.
*/
public static HttpURLConnection getConnection(String url){
System.out.println("URL: " + url);
HttpURLConnection hcon = null;
try{
hcon = (HttpURLConnection)new URL(url).openConnection();
hcon.setReadTimeout(30000); //Timeout set at 30 seconds
hcon.setRequestProperty("User-Agent", "android:com.example.reddittestappbydrew:v0.0.1");
}catch(MalformedURLException e){
Log.e("getConnection()", "Invalid URL: " +e.toString());
}catch (IOException e){
Log.e("getConnection()", "Could not connect: " + e.toString());
}
return hcon;
}
/*
A utility method that reads the contents of a url and returns them as a string
*/
public static String readContents(String url){
HttpURLConnection hcon = getConnection(url);
if(hcon == null) return null;
try{
StringBuffer sb = new StringBuffer(8192);
String tmp = "";
BufferedReader br = new BufferedReader(new InputStreamReader(hcon.getInputStream()));
while((tmp = br.readLine()) != null){
sb.append(tmp).append("\n");
}
br.close();
return sb.toString();
}catch(IOException e){
Log.d("READ FAILED", e.toString());
return null;
}
}
}
The code you have written looks pretty naive for getting html/json response data from my URL as redirects are not being handled there. Either you handle redirects in your code which you can do by checking hcon.getResponseCode() whose value should be 200 for you to read the data successfully. In case it is not 200 and something else like 301 (redirects) or 403 (authorization required), you need to handle these responses accordingly.
Here I am giving you a simple code which uses HttpClient (I am using httpclient-4.2.1) library from apache, and gets the response back as String.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.fileupload.util.Streams;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpUtils {
private static Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class);
public static String getResponse(String url) throws IOException {
return getResponse(url, "UTF-8");
}
public static String getResponse(String url, String characterEncoding) throws IOException {
return getByteArrayOutputStream(url).toString(characterEncoding);
}
public static byte[] getBytes(String url) throws IOException {
return getByteArrayOutputStream(url).toByteArray();
}
public static ByteArrayOutputStream getByteArrayOutputStream(String url) throws IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpclient.execute(httpGet);
LOGGER.debug("Status Line: " + response.getStatusLine());
HttpEntity resEntity = response.getEntity();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Streams.copy(resEntity.getContent(), byteArrayOutputStream, true);
return byteArrayOutputStream;
}
public static void main(String[] args) throws IOException {
System.out.println(getResponse("https://www.reddit.com/r/AskReddit/.json"));
}
}
Use this code to achieve what you want and in case you don't want to use HTTPClient API, then modify your existing code to handle http status codes but it would be simple for you to use above code.