I've been trying to figure out how to read a HttpURLConnection. According to this example: http://www.vogella.com/tutorials/AndroidNetworking/article.html , the following code should work. However, readStream never fires, and I'm not logging any lines.
I do get that the InputStream is passed through the buffer and all, but for me the logic breaks down in the readStream method, and then mostly the empty string 'line' and the while statement. What exactly is happening there / should happen there, and how would I be able to fix it? Also, why do I have to create the url in the Try statement? It gives back a Unhandled Exception; java.net.MalformedURLException.
Thanks in advance!
static String SendURL(){
try {
URL url = new URL("http://www.google.com/");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
readStream (con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
return ("Done");
}
static void readStream(InputStream in) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
Log.i("Tag", line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
There are a bunch of things wrong with the code I posted in the question. Here is a working example:
public class GooglePlaces extends AsyncTask {
public InputStream inputStream;
public GooglePlaces(Context context) {
String url = "https://www.google.com";
try {
HttpRequest httpRequest = requestFactory.buildGetRequest(new GenericUrl(url));
HttpResponse httpResponse = httpRequest.execute();
inputStream = httpResponse.getContent();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
try {
for (String line = null; (line = bufferedReader.readLine()) != null;) {
builder.append(line).append("\n");
Log.i("GooglePlacesTag", line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
It appears you are not connecting your HTTPUrlClient try con.connect()
Related
I am trying to turn a url (its just text) into a string and I am reading the url with a BufferedReader. However, I keep getting a Premature EOF exception. Here is what I have so far.
try {
URL sUrl = new URL(url);
String result = "";
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(sUrl.openStream()));
String av;
while ((av = br.readLine()) != null) {
result += av;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(result.length());
} catch (Exception e) {
e.printStackTrace();
}
Also, I tried implementing this solution, which I saw on another stackoverflow thread.
try {
URL oracle = new URL(url);
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
StringBuffer input = new StringBuffer();
int BUFFER_SIZE = 2000000;
char[] buffer = new char[BUFFER_SIZE];
int charsRead = 0;
while ((charsRead = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
input.append(buffer, 0, charsRead);
}
in.close();
System.out.println(input.toString().length());
} catch (Exception e) {
e.printStackTrace();
}
Both of these approached lead to the same error occuring at the .read / .readLine part of my code.
Here is the stacktrace.
java.io.IOException: Premature EOF
at java.base/sun.net.www.http.ChunkedInputStream.fastRead(ChunkedInputStream.java:257)
at java.base/sun.net.www.http.ChunkedInputStream.read(ChunkedInputStream.java:689)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:133)
at java.base/sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3501)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at com.github.doomsdayrs.jikan4java.ExampleClass.main(ExampleClass.java:99)
Been looking for a way to fix this issue. Read all the previous answers but none helped me out.
Could it be any error with SonarQube?
public class Br {
public String loader(String FilePath){
BufferedReader br;
String str = null;
StringBuilder strb = new StringBuilder();
try {
br = new BufferedReader(new FileReader(FilePath));
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f){
System.out.println(FilePath+" does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
}
return strb.toString();
}
}
You are not calling br.close() which means risking a resource leak. In order to reliably close the BufferedReader, you have two options:
using a finally block:
public String loader(String FilePath) {
// initialize the reader with null
BufferedReader br = null;
String str = null;
StringBuilder strb = new StringBuilder();
try {
// really initialize it inside the try block
br = new BufferedReader(new FileReader(FilePath));
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f) {
System.out.println(FilePath + " does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
} finally {
// this block will be executed in every case, success or caught exception
if (br != null) {
// again, a resource is involved, so try-catch another time
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return strb.toString();
}
using a try-with-resources statement:
public String loader(String FilePath) {
String str = null;
StringBuilder strb = new StringBuilder();
// the following line means the try block takes care of closing the resource
try (BufferedReader br = new BufferedReader(new FileReader(FilePath))) {
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
} catch (FileNotFoundException f) {
System.out.println(FilePath + " does not exist");
return null;
} catch (IOException e) {
e.printStackTrace();
}
return strb.toString();
}
Seems like you just want to read all lines from a file. You could use this:
public String loader(String FilePath) {
try(Scanner s = new Scanner(new File(FilePath).useDelimiter("\\A")) {
return s.hasNext() ? s.next() : null;
} catch(IOException e) {
throw new UncheckedIOException(e);
}
}
The code you wrote is indeed leaking resources as you're not closing your BufferedReader. The following snippet should do the trick:
public String loader(String filePath){
String str = null;
StringBuilder strb = new StringBuilder();
// try-with-resources construct here which will automatically handle the close for you
try (FileReader fileReader = new FileReader(filePath);
BufferedReader br = new BufferedReader(fileReader);){
while ((str = br.readLine()) != null) {
strb.append(str).append("\n");
}
}
catch (FileNotFoundException f){
System.out.println(filePath+" does not exist");
return null;
}
catch (IOException e) {
e.printStackTrace();
}
return strb.toString();
}
If you're still having issues with this code, then yes, it's SonarQubes fault :-)
I am passing the url https://www.reddit.com/r/wallpapers/top/.json into my method for getting the JSON array of a subreddit. However, it only returns the JSON array for the hot category rather than the top or new categories. I have checked the URL and code thoroughly and have tried other different formats of the URL to only get the same results. For some reason all JSON gets all return only the hot page or default subreddit URL. But when I visit the URL in my browser that I've linked, it displays the correct JSON array for the top category. (Android Studio)
Here's the beginning of my JSON task that returns the array:
private class JsonTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = null;
try {
stream = connection.getInputStream();
} catch (Exception e) {
Log.e("Subreddit Closed", urlString);
connection.disconnect();
return null; //if can't retrieve JSON file
}
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
Update: This was an issue with Reddit's API, it is now working as expected. Take caution of URL formats as */hot/.json is equivalent to */.json
My query is how to change how to change address in URL (http://localhost:8080/HELLO_WORLD). I change HELLO_WORLD to desire word.
#Override
public Response serve(IHTTPSession session) {
String answer = "";
BufferedReader reader = null;
try {
reader = new BufferedReader(
new InputStreamReader(appContext.getAssets().open("block.html")));
// do reading, usually loop until end of file reading
String mLine;
while ((mLine = reader.readLine()) != null) {
//process line
answer += mLine;
}
} catch (IOException e) {
//log the exception
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
//log the exception
Log.d("BABAR", "EXception occured in serve()");
}
}
}
return newFixedLengthResponse(answer);
}
please suggest me how to change
I donĀ“t know if this is what you want, but you can try.
You have to follow the steps:
1- Create a local to store your server files;
2-Then change the response in the class that is implementing the NanoHttp server to something like this:
#Override
public Response serve(IHTTPSession session) {
String answer = "";
try{
FileReader filereader = new FileReader(contextoMain.local(localyourstorethefiles)+"/yourfolder/yourfile.html");
BufferedReader reader = new BufferedReader(filereader);
String line = "";
while ((line = reader.readLine()) != null) {
answer += line;
}
reader.close();
}catch(IOException ioe) {
Log.w("Httpd", ioe.toString());
}
return newFixedLengthResponse(answer);
}
3 - Then, call the localhost:8080 without putting the 8080/yourfolder/yourfile
If you go to http://www.elven.ee/ip/ - you can see it gives ip. If you refresh, it gives different port.
How can I get that IP into android? I don't know how to make it also update after like every 5 seconds, but right now I want to know how can i get it into my phone. I want to display it as TextView :).
#mopsled solution did not work for me, so here is mine:
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = (TextView) findViewById(R.id.textView1);
String ip = "";
final DefaultHttpClient httpClient = new DefaultHttpClient();
final HttpGet httpGet = new HttpGet("http://www.elven.ee/ip/");
try {
final HttpResponse response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
ip = getString(response);
}
} catch (final ClientProtocolException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
tv.setText(ip);
}
private static String getString(HttpResponse response) {
final HttpEntity retEntity = response.getEntity();
if (retEntity != null) {
InputStream instream = null;
try {
instream = retEntity.getContent();
} catch (final IllegalStateException ise) {
ise.printStackTrace();
} catch (final IOException ioe) {
ioe.printStackTrace();
}
final String result = convertStreamToString(instream);
return result;
} else {
return "";
}
}
private static String convertStreamToString(final InputStream is) {
final BufferedReader reader = new BufferedReader(new InputStreamReader(is));
final StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (final IOException ioe) {
ioe.printStackTrace();
} finally {
try {
is.close();
} catch (final IOException ioe) {
ioe.printStackTrace();
}
}
return sb.toString().trim();
}
}
EDIT: Fixed code
Try a HTTPURLConnection (a simplified version of an example found here):
StringBuilder content = new StringBuilder();
try {
URL url = new URL("http://www.elven.ee/ip/");
URLConnection urlConnection = url.openConnection();
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line + "\n");
}
bufferedReader.close();
} catch(Exception e) {
e.printStackTrace();
}
String myIp = content.toString();