2011-02-25 10 views
7

मेरा कोड (नीचे पुन: उत्पादित), एक यूआरएल से कनेक्ट होता है और फ़ाइल को एंड्रॉइड पर डिस्क पर डाउनलोड करता है। सभी मानक सामान। जब मैं अपने कोड पर एक सबडोमेन के माध्यम से एक्सेस किए गए एस 3 पर एक फ़ाइल पर इस कोड का उपयोग करने की कोशिश करता हूं (उदाहरण के लिए foo.example.com => बाल्टी foo.example.com कहा जाता है), यह अक्सर विफल रहता है। पता चला है (काम कर्ल आदेश का उपयोग ..एंड्रॉइड/जावा: HttpURLConnection पुनर्निर्देशित फ़ाइल के शीर्षलेख (जैसे S3 पर) वापस नहीं करता है

"curl -v -L -X GET http://foo.example.com/f/a.txt") 

.. वहाँ एक रीडायरेक्ट यहां चल रहा है।

फ़ाइल डाउनलोड ठीक काम करता है, के रूप में HttpURLConnection डिफ़ॉल्ट रूप से रीडायरेक्ट का पालन करेंगे, लेकिन कॉल कि आवश्यकता है कि शीर्ष लेख जानकारी (getContentLength, getHeaderFieldDate ("Last-Modified", 0) आदि) रिटर्न 307 रीडायरेक्ट से हेडर हैं, और नहीं वास्तविक फ़ाइल thats डाउनलोड किया।

किसी को भी पता है कि यह चारों ओर पाने के लिए?

धन्यवाद

File local = null; 
     try { 


      Log.i(TAG, "Downloading file " + source); 
      conn = (HttpURLConnection) new URL(source).openConnection(); 
      fileSize = conn.getContentLength(); // ** THIS IS WRONG ON REDIRECTED FILES 
      out = new BufferedOutputStream(new FileOutputStream(destination, false), 8 * 1024); 
      conn.connect(); 

      stream = new BufferedInputStream(conn.getInputStream(), 8 * 1024); 

      byte[] buffer = new byte[MAX_BUFFER_SIZE]; 

      while (true) { 
       int read = stream.read(buffer); 

       if (read == -1) { 
        break; 
       } 
       // writing to buffer 
       out.write(buffer, 0, read); 
       downloaded += read; 

       publishProgress(downloaded, fileSize); 

       if (isCancelled()) { 
        return "The user cancelled the download"; 
       } 

      } 
     } catch (Exception e) { 
      String msg = "Failed to download file " + source + ". " + e.getMessage(); 
      Log.e(TAG, msg); 
      return msg; 
     } finally { 
      if (out != null) { 
       try { 
        out.flush(); 
        out.close(); 
       } catch (IOException e) { 
        Log.e(TAG, "Failed to close file " + destination); 
        e.printStackTrace(); 
       } 
      } 

      if (stream != null) { 
       try { 
        stream.close(); 
       } catch (IOException e) { 
        Log.e(TAG, "Failed to close file " + destination); 
        e.printStackTrace(); 
       } 

      } else { 

       long dateLong = conn.getHeaderFieldDate("Last-Modified", 0); // ** THIS IS WRONG ON REDIRECTED FILES 

       Date d = new Date(dateLong); 
       local.setLastModified(dateLong); 
      } 

उत्तर

10

क्या आपने रीडायरेक्ट को गलत पर सेट करने का प्रयास किया है और इसके साथ पुनर्निर्देशित यूआरएल और संबंधित हेडर फ़ील्ड मैन्युअल रूप से कैप्चर करने का प्रयास किया है?

उदाहरण के लिए कुछ इस तरह:

URL url = new URL(url); 
HttpURLConnection ucon = (HttpURLConnection) url.openConnection(); 
ucon.setInstanceFollowRedirects(false); 
URL secondURL = new URL(ucon.getHeaderField("Location")); 
URLConnection conn = secondURL.openConnection(); 

यह उदाहरण रीडायरेक्ट URL कैप्चर करता है, लेकिन आप आसानी से किसी भी अन्य शीर्ष लेख क्षेत्र के लिए प्रयास करने के लिए इस tweak सकता है। क्या यह मदद करता है?

+0

धन्यवाद। मुझे लगता है कि यह एकाधिक रीडायरेक्ट के साथ थोड़ा सा झुकाव प्राप्त करेगा लेकिन यह –

+1

की मदद कर सकता है मैं विभिन्न एंड्रॉइड घटकों के लिए रीडायरेक्टिंग कोड में अन्य अजीब गेटचास में चला गया हूं। यहां तक ​​कि एक ही ओएस संस्करण पर, विभिन्न डिवाइस उन्हें अलग-अलग संभालेंगे। परिणामस्वरूप हम मैन्युअल रीडायरेक्ट पर स्विच कर चुके हैं। –

+0

आह, दिलचस्प। मैं HttpURLConnection के बजाय apache HttpClient का उपयोग करने के साथ प्रयोग कर रहा हूं, और यह मेरे लिए काम कर रहा है (अब तक!)। आपके एंड्रॉइड घटकों के साथ क्या समस्याएं हैं? –

0

ठीक है, मैं थोड़ा सा खेल रहा हूं और यह कोड, जो HttpUrlConnection की बजाय HttpClient लाइब्रेरी का उपयोग करता है ठीक काम करता है। हेडर जो यह लौटाता है वह अंतिम रीडायरेक्ट हॉप के हैं। कम से कम उन उपकरणों पर जिन पर मैंने इसका परीक्षण किया है।

HttpClient client = null; 
HttpGet get = null; 
HttpResponse response = null; 
try { 
client = new DefaultHttpClient(); 
get = new HttpGet(source); 
response = client.execute(get); 

Header contentSize = response.getFirstHeader("Content-Length"); 
if (contentSize != null) { 
String value = contentSize.getValue(); 
fileSize = Long.parseLong(value); 
} 
if (fileSize == -1) { 
    Log.e(TAG, "Failed to read the content length for the file " + source); 
} 

Header lastModified = response.getFirstHeader("Last-Modified"); 
lastModifiedDate = null; 
if (lastModified != null) { 
    lastModifiedDate = DateUtils.parseDate(lastModified.getValue()); 
} 
if (lastModifiedDate == null) { 
    Log.e(TAG, "Failed to read the last modified date for the file " + source); 
} 

out = new BufferedOutputStream(new FileOutputStream(destination, false), 8 * 1024);  // false means don't append 
stream = new BufferedInputStream(response.getEntity().getContent(), 8 * 1024); 

byte[] buffer = new byte[MAX_BUFFER_SIZE]; 

int count = 0; 
while (true) { 
    int read = stream.read(buffer); 

    if (read == -1) { 
     break; 
    } 
    // writing to buffer 
    out.write(buffer, 0, read); 
    downloaded += read; 

    publishProgress(downloaded, fileSize); 

    if (isCancelled()) { 
     Log.w(TAG, "User Cancelled"); 
     return; // NOTE that onPostExecute is not called here.. 
    } 
}// end of while 

publishProgress(downloaded, fileSize); 

} catch (Exception e) { 
String msg = "Failed to download file " + source + ". " + e.getMessage(); 
Log.e(TAG, msg); 
return msg; 
} finally { 
if (out != null) { 
    try { 
     out.flush(); 
     out.close(); 
    } catch (IOException e) { 
     Log.e(TAG, "Failed to close file " + destination); 
     e.printStackTrace(); 
    } 
} 

if (stream != null) { 
    try { 
     stream.close(); 
    } catch (IOException e) { 
     Log.e(TAG, "Failed to close file " + destination); 
     e.printStackTrace(); 
    } 
} 
} 
1

httpclient-android उपयोग पर विचार करें। आप इस के साथ पुनर्निर्देशन के बाद सही हेडर मिलना चाहिए:

HttpClient client = HttpClientBuilder.create().build(); 
HttpGet request = new HttpGet(YOUR_URL); 
HttpResponse response = client.execute(request); 
response.getAllHeaders() 

ध्यान दें कि Android httpclient के एक पुराने संस्करण के साथ आता है, लेकिन जैसा कि आप सूचना यह एक ही समस्या है। आप एक नए संस्करण के लिए "httpclient-android" आयात करने के लिए actually need

नोट: कोड स्निपेट v4.3 के लिए है। अन्य संस्करणों के लिए, नियमित अपाचे HttpClient में इसे कैसे करें, इसके लिए देखें।

संबंधित मुद्दे