Support resumming partial downloads

Julien LepillerMon May 25 21:07:52+0200 2020

b7de40d

Support resumming partial downloads

app/src/main/java/eu/lepiller/nani/DictionaryDownloadActivity.java

2424
import java.io.OutputStream;
2525
import java.net.HttpURLConnection;
2626
import java.net.URL;
27+
import java.util.List;
2728
import java.util.Map;
2829
2930
import eu.lepiller.nani.dictionary.Dictionary;

178179
179180
                    // .sha256 file now downloaded
180181
                    url = new URL(uri);
182+
                    file = e.getValue();
183+
                    long expectedLength = -1;
184+
                    boolean acceptRanges = false;
185+
                    if(file.exists()) {
186+
                        // if file exists, it is not fully downloaded, so we check whether we can
187+
                        // do a partial download
188+
                        connection = (HttpURLConnection) url.openConnection();
189+
                        connection.setRequestMethod("HEAD");
190+
                        connection.connect();
191+
                        if(connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
192+
                            expectedLength = connection.getContentLength();
193+
                            acceptRanges = connection.getHeaderFields().containsKey("accept-ranges");
194+
                            if (acceptRanges) {
195+
                                List<String> headers = connection.getHeaderFields().get("accept-ranges");
196+
                                for(String h: headers) {
197+
                                    if(h.toLowerCase().compareTo("none") == 0)
198+
                                        acceptRanges = false;
199+
                                }
200+
                            }
201+
                            Log.d(TAG, "Can do range? " + acceptRanges);
202+
                        }
203+
                        output = new FileOutputStream(file, true);
204+
                    } else {
205+
                        output = new FileOutputStream(file);
206+
                    }
207+
208+
                    long total = 0;
181209
                    connection = (HttpURLConnection) url.openConnection();
210+
                    if(expectedLength > 0 && acceptRanges && file.length() < expectedLength) {
211+
                        connection.addRequestProperty("Range", "bytes=" + file.length() + "-" + (expectedLength-1));
212+
                        total = file.length();
213+
                    }
182214
                    connection.connect();
183215
184216
                    // expect HTTP 200 OK, so we don't mistakenly save error report
185217
                    // instead of the file
186-
                    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
218+
                    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK &&
219+
                            connection.getResponseCode() != HttpURLConnection.HTTP_PARTIAL) {
187220
                        Log.e(TAG, "Server returned HTTP " + connection.getResponseCode()
188221
                                + " " + connection.getResponseMessage());
189222
                        return "Server returned HTTP " + connection.getResponseCode()

196229
197230
                    // download the file
198231
                    input = connection.getInputStream();
199-
                    file = e.getValue();
200-
                    output = new FileOutputStream(file);
201232
202-
                    long total = 0;
203233
                    while ((count = input.read(data)) != -1) {
204234
                        // allow canceling with back button
205235
                        if (isCancelled()) {