+ // The actual network request is in a `try` bracket so that `disconnect()` is run in the `finally` section even if an error is encountered in the main block.
+ try {
+ // Get the content length header, which causes the connection to the server to be made.
+ String contentLengthString = httpUrlConnection.getHeaderField("Content-Length");
+
+ // Define the file size long.
+ long fileSize;
+
+ // Make sure the content length isn't null.
+ if (contentLengthString != null) { // The content length isn't null.
+ // Convert the content length to an long.
+ fileSize = Long.parseLong(contentLengthString);
+ } else { // The content length is null.
+ // Set the file size to be `-1`.
+ fileSize = -1;
+ }
+
+ // Get the response body stream.
+ InputStream inputStream = new BufferedInputStream(httpUrlConnection.getInputStream());
+
+ // Initialize the conversion buffer byte array.
+ byte[] conversionBufferByteArray = new byte[1024];
+
+ // Initialize the downloaded kilobytes counter.
+ long downloadedKilobytesCounter = 0;
+
+ // Define the buffer length variable.
+ int bufferLength;
+
+ // Attempt to read data from the input stream and store it in the output stream. Also store the amount of data read in the buffer length variable.
+ while ((bufferLength = inputStream.read(conversionBufferByteArray)) > 0) { // Proceed while the amount of data stored in the buffer in > 0.
+ // Write the contents of the conversion buffer to the file output stream.
+ fileOutputStream.write(conversionBufferByteArray, 0, bufferLength);
+
+ // Update the file download progress snackbar.
+ if (fileSize == -1) { // The file size is unknown.
+ // Negatively update the downloaded kilobytes counter.
+ downloadedKilobytesCounter = downloadedKilobytesCounter - bufferLength;
+
+ publishProgress(downloadedKilobytesCounter);
+ } else { // The file size is known.
+ // Update the downloaded kilobytes counter.
+ downloadedKilobytesCounter = downloadedKilobytesCounter + bufferLength;
+
+ // Calculate the download percentage.
+ long downloadPercentage = (downloadedKilobytesCounter * 100) / fileSize;
+
+ // Update the download percentage.
+ publishProgress(downloadPercentage);
+ }
+ }
+
+ // Close the input stream.
+ inputStream.close();
+
+ // Close the file output stream.
+ fileOutputStream.close();
+ } finally {
+ // Disconnect the HTTP URL connection.
+ httpUrlConnection.disconnect();
+ }