2012-02-20 18 views
42

Ho un'app Android che funziona perfettamente con Android 2.xe 3.x, ma non funziona quando viene eseguito su Android 4.x.FileNotFoundException per HttpURLConnection in Ice Cream Sandwich

Il problema è in questa sezione di codice:

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

Quando l'applicazione è in esecuzione su Android 4.x, i risultati getInputStream() chiamata in un FileNotFoundException. Quando lo stesso binario è in esecuzione su versioni precedenti di Android, ha successo. Gli URL funzionano anche bene nei browser Web e con curl.

Apparentemente qualcosa su HttpURLConnection è stato modificato in ICS. Qualcuno ha idea di cosa è cambiato e/o quale potrebbe essere la correzione?

+1

I documenti dicono che 'setDoOutput (vero)' 'implica setRequestMethod ("POST")'. Che intendi? –

+0

È pensato per fare un GET. (Non ho scritto il codice, quindi non so perché "setDoOutput (true)" era lì.) –

+0

FWIW, 'setRequestMethod (" GET ")' e 'setDoOutput (true)' appaiono in un sacco di esempi codice per l'uso di 'HttpURLConnection'. Dove è documentato che costringe un POST? –

risposta

93

Provare a rimuovere la chiamata setOutput. Tratto da questo blog: a blog

Modifica: questo è necessario quando si usa una chiamata POST.

+1

Sì, abbastanza sicuro, rimuovere quella linea lo fa funzionare su ICS, e sembra funzionare ancora su Android più vecchi. –

+1

ottimo. funziona anche per me. – Durai

+3

+1000 Grazie! Sto costruendo una libreria utilizzata per accedere a un back-end. Ho passato ore a cercare di capire perché le URLConnections avrebbero funzionato dalla riga di comando, ma non quando ho caricato la libreria nel mio progetto Android. – tunneling

5

I Non so perché, ma trattare manualmente con il reindirizzamento risolve il problema.

connection.setInstanceFollowRedirects(false); 
26

Un FileNotFoundException può stato anche gettato se il server restituisce un codice di errore cattiva (ad esempio, 400 o 401). Puoi gestirlo come segue:

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

Stavo ricevendo il codice di risposta 500, perché non avevo impostato 'Content-Type', grazie per aver sottolineato che questa eccezione poteva essere lanciata in quei casi. –

+1

Per chi si chiede perché non hanno il metodo "getResponseCode()": basta lanciare la connessione a HttpURLConnection –

+1

Qualcuno sa * perché * Android lancia un'eccezione FileNotFoundException sui codici [che chiaramente non sono 404] (https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error)? –

1

Un po 'in ritardo ma puoi anche verificare il contenuto accettato. È possibile aggiungere questa riga di accettare tutti i tipi di contenuti

urlConnection.setRequestProperty("Accept","*/*"); 
Problemi correlati