FileNotFoundException for HttpURLConnection in Ice Cream Sandwich
Asked Answered
F

4

47

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?

Famine answered 20/2, 2012 at 17:45 Comment(6)
The docs say that setDoOutput(true) implies setRequestMethod("POST"). Which do you mean?Emanate
It's meant to do a GET. (I didn't write the code, so I don't know why setDoOutput(true) was there.)Famine
FWIW, setRequestMethod("GET") and setDoOutput(true) appear in a lot of sample code for using HttpURLConnection. Where is it documented that it forces a POST?Famine
HTTP Methods HttpURLConnection uses the GET method by default. It will use POST if setDoOutput(true) has been called. developer.android.com/reference/java/net/HttpURLConnection.htmlEmanate
it's quite old, but what i did is just i ommited the conn.setRequestMethod("GET") , we set the conn.setDoOutput(true) which means it's a POST and vis versaTumescent
from docs: setDoOutput(true) :Sets the flag indicating whether this {@code URLConnection} allows output. It cannot be set after the connection is established.Procurable
T
102

Try removing the setDoOutput call. Taken from this blog: a blog

Edit: This is needed when using a POST call.

Two answered 20/2, 2012 at 18:36 Comment(3)
Yeah, sure enough, removing that line makes it work on ICS, and it seems to still work on older Android as well.Famine
Note that this is needed, when making a POST request! In that case, it should be kept in place.Stir
Hey guys. What do you do when you are using a POST call?Heterogenous
D
30

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...
}
Dagenham answered 9/5, 2014 at 18:28 Comment(4)
I was getting response code 500, because I hadn't set Content-Type, thanks for pointing out that this exception might be thrown in those cases.Smocking
For anyone wondering why they don't have the "getResponseCode()" method: just cast your connection to a HttpURLConnectionLetdown
Does anyone know why Android throws a FileNotFoundException on codes which clearly aren't 404?Uplift
@DavidLord I had this error because my URL wasn't properly formatted. I used URLEncoder.encode(myURL, "UTF-8"); for the part of my URL that contained a space character, and it all went well.Patentor
R
6

I Don't know why, but dealing manually with redirection resolves the problem.

connection.setInstanceFollowRedirects(false);
Rebel answered 27/4, 2013 at 12:21 Comment(1)
In my situation, I was using an Authorization header to load a script on my website, which redirects to a pre-signed URL on Digital Ocean Spaces (S3 compatible). Android was also sending the Authorization header with the redirected request and that was causing Spaces to return a 400 error. This is on Android 5; later versions don't do this.Olander
C
1

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","*/*");
Comedic answered 22/3, 2016 at 16:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.