0

I have an asynchronous method that allows downloading files. If the middle of the download, I will remove the connection (wifi or 3g) timeout never occurs.

Always stay in the next loop waiting to return the connection:

while ((count = input.read(data)) != -1) {
        System.out.println("state 5");
        total += count;
        publishProgress((int) (total * 100 / fileLength));
        output.write(data, 0, count);
}

I do:

  private class DownloaderFile extends AsyncTask<String, Integer, String> {
        @Override
        protected String doInBackground(String... params) {
            ...
            try{
                URLConnection connection = urlFinal.openConnection();
                connection.setConnectTimeout(TIMEOUT_VALUE);
                connection.setReadTimeout(TIMEOUT_VALUE);
                connection.connect();
                int fileLength = connection.getContentLength();

                InputStream input = new BufferedInputStream(urlFinal.openStream());

                OutputStream output = new FileOutputStream(folder + params[0]);

                byte data[] = new byte[1024];
                long total = 0;
                int count;

                while ((count = input.read(data)) != -1) {
//always wait here
                    System.out.println("state 5");
                    total += count;
                    publishProgress((int) (total * 100 / fileLength));
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();
            } catch (SocketTimeoutException e) {
                System.out.println("TIMEOUT!!! " + TIMEOUT_VALUE + " elapsed.");
                callback.onDownloadEnd(DOWNLOAD_ERROR);
            }
            ...
        }
        ...
ephramd
  • 561
  • 2
  • 15
  • 41
  • This question has been asked before, but doesn't include the bit about being on a wifi: http://stackoverflow.com/q/3163693/42962 I recommend following the advice on this post: http://stackoverflow.com/a/7611294/42962 Please call getReadTimeout() and getConnectTimeout() to even see if the values you're trying to set are even being taken by the object. – hooknc Sep 24 '13 at 23:27

3 Answers3

1

This is not a great solution but it works. While I think of another solution...

while ((count = input.read(data)) != -1) {
     if (!isInternet(context)){
        callback.onDownloadEnd(DOWNLOAD_ERROR);
         return "error";
     }
     total += count;
     publishProgress((int) (total * 100 / fileLength));
     output.write(data, 0, count);
}
ephramd
  • 561
  • 2
  • 15
  • 41
0

I suspect SocketTimeoutException being the wrong exception to look for as the connection is correcty established in your test, what if you change it to Exception? Just to see if that helps.

I can see from: How to set HttpResponse timeout for Android in Java that i was mistaken.

From the information I linked I found that you probably need to set:

  // Set the default socket timeout (SO_TIMEOUT) 
  // in milliseconds which is the timeout for waiting for data.
  int timeoutSocket = 5000;
  HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
Community
  • 1
  • 1
cYrixmorten
  • 7,110
  • 3
  • 25
  • 33
  • 1
    I've tried with: `... } catch (Exception e) { System.out.println("error timeout"); callback.onDownloadEnd(DOWNLOAD_ERROR); }` But that exception does not work. – ephramd Sep 24 '13 at 22:54
  • 1
    That solution is to use http requests, I use it in other cases and the timeout works perfectly. The problem is in the above code with URLConnection that allows downloading of a file (eg MP3). – ephramd Sep 24 '13 at 23:12
0

Whatever the cause may be I'm guessing when 3g/wifi is no longer available the thread that reads from socket is blocked.

One approach you can take here is to perform the socket read on a separate thread, and use Thread.join(long millis) method to wait up to maximum milliseconds for it to complete.

Thread t = new Thread(new Runnable() {
             void run() {
               ...
               while ((count = input.read(data)) != -1) {
                 ...
               }
               ...
             }
           }).start();

t.join(TIMEOUT_VALUE); // will wait here until either the thread t is done or times out
gerrytan
  • 40,313
  • 9
  • 84
  • 99
  • 1
    This is not a solution, depending on the connection speed, the file may take some time to download, I do not know the time and therefore useless. – ephramd Sep 24 '13 at 23:09
  • hence why do you even bother expecting your code to timeout? The premise here is you expect timeout to occur if the download took longer than you expected? – gerrytan Sep 24 '13 at 23:11