L'application sur laquelle je travaille est compatible avec Android 2.3 et plus. Comme le gestionnaire de téléchargement ne supporte pas https dans 2.3 (je ne comprends pas pourquoi), je suis en train d'implémenter ma propre version.
Le problème que j'ai est que si Android change de réseau (wifi à 3g etc) lors du téléchargement du contenu, j'obtiens l'erreur suivante.
06-14 17:26:48.770: W/System.err(15648): javax.net.ssl.SSLException: Read error: ssl=0x270420: I/O error during system call, Connection timed out
06-14 17:26:48.770: W/System.err(15648): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_read(Native Method)
06-14 17:26:48.770: W/System.err(15648): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:788)
06-14 17:26:48.770: W/System.err(15648): at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
06-14 17:26:48.770: W/System.err(15648): at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
06-14 17:26:48.770: W/System.err(15648): at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:174)
06-14 17:26:48.770: W/System.err(15648): at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:188)
06-14 17:26:48.770: W/System.err(15648): at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:178)
06-14 17:26:48.770: W/System.err(15648): at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:140)
06-14 17:26:48.770: W/System.err(15648): at java.io.BufferedInputStream.read(BufferedInputStream.java:324)
06-14 17:26:48.770: W/System.err(15648): at java.io.FilterInputStream.read(FilterInputStream.java:133)
06-14 17:26:48.770: W/System.err(15648): at net.doo.download.ManualDocDownloader$AsyncDocDownloader.doInBackground(ManualDocDownloader.java:126)
06-14 17:26:48.770: W/System.err(15648): at net.doo.download.ManualDocDownloader$AsyncDocDownloader.doInBackground(ManualDocDownloader.java:86)
06-14 17:26:48.770: W/System.err(15648): at android.os.AsyncTask$2.call(AsyncTask.java:185)
06-14 17:26:48.770: W/System.err(15648): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
06-14 17:26:48.780: W/System.err(15648): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
06-14 17:26:48.780: W/System.err(15648): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
06-14 17:26:48.840: W/System.err(15648): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
06-14 17:26:48.845: W/System.err(15648): at java.lang.Thread.run(Thread.java:1019)
Le code qui pose problème ressemble à ceci...
public class AsyncDocDownloader extends AsyncTask<String, Integer, Boolean> {
private int id;
private Notification notification;
public AsyncDocDownloader(int id, Notification notification) {
this.id = id;
this.notification = notification;
}
@Override
protected void onProgressUpdate(Integer... values) {
notification.contentView.setProgressBar(R.id.status_progress, 100, values[0], false);
notificationManager.notify(id, notification);
}
@Override
protected Boolean doInBackground(String... values) {
try {
HttpGet get = new HttpGet(values[0]);
HttpResponse resp = httpClientProvider.get().execute(get, context);
File dooDirectory = directoryProvider.get();
File fileName = new File(dooDirectory, values[1]);
InputStream input = new BufferedInputStream(resp.getEntity().getContent());
OutputStream output = new FileOutputStream(fileName);
int fileLength = Integer.valueOf(resp.getHeaders("Content-Length")[0].getValue());
int step = fileLength/20;
int counter = 0;
int progress = 0;
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
if(total > counter){
progress = progress + 5;
publishProgress(progress);
counter = step + counter;
}
output.write(data, 0, count);
}
output.close();
input.close();
Log.d("DownloadDoc", "Completed download");
return true;
} catch (IOException e) {
Log.d("DownloadDoc", "IOException");
e.printStackTrace();
return false;
}
}
@Override
protected void onPostExecute(Boolean success) {
Log.d("DownloadDoc", "onPostExecute Called");
if (success) {
Intent i = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
application.sendBroadcast(i);
} else {
notification.flags = notification.flags | Notification.DEFAULT_ALL;
notification.contentView.setTextViewText(R.id.status_text, "failed");
notificationManager.notify(id, notification);
}
}
}
Le httpClient qui est passé par le fournisseur est configuré comme suit (le fournisseur est parce que j'utilise roboguice)
HttpParams params = new BasicHttpParams();
HttpRequestRetryHandler retryhandler = new DefaultHttpRequestRetryHandler(6, true);
// The params are read in the ctor of the pool constructed by
// ThreadSafeClientConnManager, and need to be set before constructing it.
ConnManagerParams.setMaxTotalConnections(params, 200);
ConnPerRoute cpr = new ConnPerRoute() {
@Override
public int getMaxForRoute(HttpRoute httpRoute) {
return 50;
}
};
ConnManagerParams.setMaxConnectionsPerRoute(params, cpr);
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLCertificateSocketFactory.getHttpSocketFactory(50000,
new SSLSessionCache(context)), 443));
ClientConnectionManager conManager = new ThreadSafeClientConnManager(params, schemeRegistry);
DefaultHttpClient httpClient = new DefaultHttpClient(conManager, new BasicHttpParams());
httpClient.setHttpRequestRetryHandler(retryhandler);
Merci pour tout conseil