FileNotFoundException for HttpURLConnection in Ice Cream Sandwich - android

I have an Android app that works fine with Android 2.x and 3.x, but it fails when run on Android 4.x.
The problem is in this section of code:
URL url = new URL("http://blahblah.blah/somedata.xml");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
When the application is running on Android 4.x, the getInputStream() call results in a FileNotFoundException. When the same binary is running on earlier versions of Android, it succeeds. The URLs also work fine in web browsers and with curl.
Apparently something about HttpURLConnection has changed in ICS. Does anybody have any idea what has changed, and/or what the fix might be?

Try removing the setDoOutput call. Taken from this blog:
a blog
Edit: This is needed when using a POST call.

A FileNotFoundException may also been thrown if the server returns a bad error code (e.g., 400 or 401). You can handle this as follows:
int responseCode = con.getResponseCode(); //can call this instead of con.connect()
if (responseCode >= 400 && responseCode <= 499) {
throw new Exception("Bad authentication status: " + responseCode); //provide a more meaningful exception message
}
else {
InputStream in = con.getInputStream();
//etc...
}

I Don't know why, but dealing manually with redirection resolves the problem.
connection.setInstanceFollowRedirects(false);

A little late but you can also verify the accepted content. You can add this line to accept all kinds of contents
urlConnection.setRequestProperty("Accept","*/*");

Related

Why is the example from developer.android not working

I'm about to code an Android app (using A.Studio 3.5.1) that should connect to a back-end using https. I'm quite new to the techniques so I looked at https://developer.android.com/training/articles/security-ssl.html#HttpsExample
I has four lines of code:
URL url = new URL("https://wikipedia.org");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);
When I try it I get a red text;
new URL gives MalformedURLException
url.openConnection() gives IOException,
urlConnection.getInputStream() also
copyInputStreamToOutputStream is not found.
I have read about copyInputStreamToOutputStream, that it can be solved
copyInputStreamToOutputStream(in, System.out)
and
Easy way to write contents of a Java InputStream to an OutputStream
I tried the first way, using apache commons, with no success.
I'm mostly curious about the exceptions.
I will try another walk-through on
https://codelabs.developers.google.com/codelabs/android-network-security-config/
But it would be nice to learn about this...
I have faced similar situations many times. This occur because the webpage you are trying to reach doesn't return anything as a response after connection is established. So the parsing returns IOException as there is nothing to read in the response of URL after connection.
newURL is returning MalformedURLException because your url contains -- " -- which should be escaped as these are special characters.
Hope this helps.

Does HttpURLConnection work for sdk22?

Does HttpURLConnection that works for android API 23 also work for android API22?
I'm trying to program for android version over 4.0.
I am unsure if the difference between sdk22 and sdk23 will cause a problem
// http client
URL url = new URL(url1);
HttpURLConnection httpClient = (HttpURLConnection) url.openConnection();
httpClient.setRequestMethod("POST");
httpClient.setUseCaches(false);
httpClient.setDoInput(true);
httpClient.setDoOutput(true);
httpClient.setRequestProperty("Connection", "Keep-Alive");
httpClient.addRequestProperty("Content-length", reqEntity.getContentLength() + "");
OutputStream os = httpClient.getOutputStream();
reqEntity.writeTo(httpClient.getOutputStream());
os.close();
httpClient.connect();
if (httpClient.getResponseCode() == HttpURLConnection.HTTP_OK) {
return readStream(httpClient.getInputStream());
Yes it will work without any issues, and the difference will not cause any problem
HttpUrlConnection is available in from API Level 1 , you can further get more insight from the docs.
Its a good practice to use HttpUrlConnection over deprecated Apache HttpClient classes,

HttpURLConnection getInputStream() returns empty for specific device

Im experiencing a strange behaviour when using HttpURLConnection getInputStream() on a different devices. On all devices except "Alcatel" im getting a valid input stream only for Alcatel devices im getting a different(empty) kind of input stream:
All devices except alcatel
Alcatel devices
Im making the exact same call and getting 200 for all the devices.
The code is pretty straightforward:
urlObj = new URL(url);
urlConnection = (HttpURLConnection)urlObj.openConnection();
urlConnection.setRequestMethod(method);
urlConnection.setDoInput(true);
urlConnection.setConnectTimeout(timeout);
urlConnection.setReadTimeout(timeout);
urlConnection.setDoOutput(true);
urlConnection.setFixedLengthStreamingMode(body.length);
urlConnection.setRequestProperty(HEADER_KEY_CONTENT_LENGTH, String.valueOf(body.length));
urlConnection.getOutputStream().write(body);
int responseCode = urlConnection.getResponseCode();
InputStream in = urlConnection.getInputStream();
Any suggestions?
Please check if you need to have proxy setting for alcatel. httpurlconnection may fail without proper proxy gateway.

java.io.FileNotFoundException: https://api.instagram.com/v1/media/search

Why is the following code
URL url = new URL(urlStr);
Log.d(TAG, "Opening URL " + url.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.connect();
String response = streamToString(urlConnection.getInputStream());
always giving me the following Exception at urlConnection.getInputStream()?
W/System.err(16253): java.io.FileNotFoundException: https://api.instagram.com/v1/media/search/access_token=1559619173.3c922fe.4fd71e26225a42a0a03fdd90ef8679a6?lat=48.858318956&lng=2.294427258&distance=500
W/System.err(16253): at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
W/System.err(16253): at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
W/System.err(16253): at br.com.dina.oauth.instagram.InstagramApp$5.run(InstagramApp.java:192)
You should remove urlConnection.setDoOutput(true); line because setDoOutput method force POST but instagram api work GET method.
You can also check this issue.
https://github.com/thiagolocatelli/android-instagram-oauth/issues/2
The code throwing the exception can be found for example in the okhttp github (Android uses that internally). The lines responsible are:
if (getResponseCode() >= HTTP_BAD_REQUEST) {
throw new FileNotFoundException(url.toString());
}
That simply means that the url you've provided did not result in a successful response. Throwing a *File*NotFoundException is behavior okhttp just copies from other implementations. Why someone chose this particular exception is beyond me.
If you simply put the url in the error message into a browser you'll see that you get a "Not found" page.
Explanation is simple: You're building the URL wrong. Instead of
search/access_token=...?lat=...
it needs to be
search?access_token=...&lat=...
access_token is a url parameter, not part of the path so it needs to get the ? as separator while lat becomes the second parameter which means ? needs to turn into &.

setRequestProperty throwing java.lang.IllegalStateException: Cannot set request property after connection is made

I am getting java.lang.IllegalStateException:
java.lang.IllegalStateException: Cannot set request property after connection is made error when setRequestProperty method is called after
url.openConnection();
Here is what i am trying:
URL url = new URL("https://49.205.102.182:7070/obsplatform/api/v1/mediadevices/545b801ce37e69cc");
urlConnection = (HttpsURLConnection) url
.openConnection();
urlConnection.setRequestProperty("Content-Type","application/json");
any suggestions please? Thanks in advance.
This usually happens if you have in the debug watchers calls, such as conn.getResponseCode() or anything that queries the request result before the request was actually issued or completed.
This causes, that during debug, a request is performed by the watcher, before having properly set you request, and then it becomes invalid.
I only have this issue while in debugging mode,
Run without debugging (You can print logs) everything should work fine
The obvious thing is to think that you need to add properties before calling open on the URL. this however is not the case. i have seen many samples of settings being set AFTER url has been open (as counter intuitive as that is).
the problem in my case is that i had conn.getResponseCode() added in my watch list. removed that and all good.
... tricky.
please check below code
HttpURLConnection httpcon = (HttpURLConnection) ((new URL("a url").openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestMethod("POST");
httpcon.connect();
I was getting the same exception on setRequestProperty("Range","byte=" + downloadedSize + "-") .
After adding connection.setChunkedStreamingMode(0); the issue disappeared
I'm having the same issue.
I was observing this issue on Nexus 5. Code of my app constantly fails with the same exception (or its twin brother "cannot set request method ..")
What I've observed that it happens if i leave phone for a while. One it starts failing it fails all the time - but if i restart phone/emulator it's ok once again).
My suspicion is its either some bug in connection pooling on framework side, or somewhere in code resources are leaked.
i found the problem it's about ordering the code, if you are trying to add header and post parameters both, it's important to be careful about this
HttpURLConnection connection = (HttpURLConnection) urlConnection;
//// Add Request Headers
for (NameValuePair nvp :
request[0].getHeaderParams()) {
connection.setRequestProperty(nvp.getName(),nvp.getValue());
}
// done
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
//// Add Post Parameters
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
List<NameValuePair> params = new ArrayList<>(request[0].getPostParams());
bufferedWriter.write(getQuery(params));
// done
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.flush();
outputStream.close();
connection.connect();
in here, i have added header parameters then set setDoInput and setDoOutput then setRequestMethod and finally you can add POST parameters.
i don't know what is wrong with setRequestMethod but i think its preparing the connection by opening it or something and that's why it throws exception
not invoke setRequestProperty after write byte to OutputStream.
OutputStream os = connection.getOutputStream();
os.write("k=v".getBytes());
os.close();
you should invoke setRequestProperty above the code
To avoid the error:
java.lang.IllegalStateException: Cannot set request property after connection is made
We have to check the connection response before access the request header fields :
URL url = new URL("https://49.205.102.182:7070/obsplatform/api/v1/mediadevices/545b801ce37e69cc");
urlConnection = (HttpsURLConnection) url
.openConnection();
//Check connection
if(urlConnection.getResponseCode() == 200/*Successful*/) {
urlConnection.setRequestProperty("Content-Type","application/json");
...
...
}

Categories

Resources