2012-02-20 11 views
42

Tengo una aplicación de Android que funciona bien con Android 2.xy 3.x, pero falla cuando se ejecuta en Android 4.x.FileNotFoundException para HttpURLConnection en Ice Cream Sandwich

El problema es en esta sección del código:

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(); 

Cuando la aplicación se ejecuta en Android 4.x, los resultados getInputStream() de llamadas en una FileNotFoundException. Cuando el mismo binario se ejecuta en versiones anteriores de Android, tiene éxito. Las URL también funcionan bien en los navegadores web y con curl.

Aparentemente algo sobre HttpURLConnection ha cambiado en ICS. ¿Alguien tiene alguna idea de qué ha cambiado y/o cuál es la solución?

+1

Los documentos dicen que 'setDoOutput (verdadero)' 'implica setRequestMethod ("POST")'. ¿A qué te refieres? –

+0

Está destinado a hacer un GET. (No escribí el código, así que no sé por qué 'setDoOutput (true)' estaba allí.) –

+0

FWIW, 'setRequestMethod (" GET ")' y 'setDoOutput (true)' aparecen en una gran cantidad de muestras código para usar 'HttpURLConnection'. ¿Dónde está documentado que fuerza un POST? –

Respuesta

93

Intente eliminar la llamada setDoOutput. Tomado de este blog: a blog

Editar: Esto es necesario cuando se utiliza una llamada POST.

+1

Sí, por supuesto, eliminar esa línea hace que funcione en ICS, y parece que todavía funciona en Android anterior. –

+1

genial. está trabajando para mí también. – Durai

+3

+1000 ¡Gracias! Estoy construyendo una biblioteca utilizada para acceder a un back-end. Pasé horas intentando descubrir por qué las URLConnections funcionarían desde la línea de comandos, pero no cuando cargué la biblioteca en mi proyecto de Android. – tunneling

5

I No sé por qué, pero tratar manualmente con la redirección resuelve el problema.

connection.setInstanceFollowRedirects(false); 
26

A FileNotFoundException también puede sido arrojado si el servidor devuelve un código de error mala (por ejemplo, 400 o 401). Puede manejar esto de la siguiente manera:

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... 
} 
+2

Recibía el código de respuesta 500 porque no había configurado 'Content-Type', gracias por señalar que esta excepción podría arrojarse en esos casos. –

+1

Para cualquiera que se pregunte por qué no tienen el método "getResponseCode()": simplemente transfiera su conexión a HttpURLConnection –

+1

¿Alguien sabe * por qué * Android arroja una excepción FileNotFoundException en códigos [que claramente no son 404] (https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error)? –

1

Un poco tarde pero también puede verificar el contenido aceptado. Puede añadir esta línea a aceptar todo tipo de contenidos

urlConnection.setRequestProperty("Accept","*/*"); 
Cuestiones relacionadas