1 package com.moiseum.wolnelektury.connection.downloads;
3 import android.os.Environment;
4 import android.support.annotation.NonNull;
5 import android.util.Log;
7 import com.moiseum.wolnelektury.base.WLApplication;
8 import com.moiseum.wolnelektury.connection.models.MediaModel;
10 import org.greenrobot.eventbus.EventBus;
13 import java.io.FileOutputStream;
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.io.OutputStream;
17 import java.util.List;
19 import io.reactivex.Completable;
20 import okhttp3.ResponseBody;
22 import static android.os.Environment.isExternalStorageRemovable;
25 * Created by Piotr Ostrowski on 10.05.2017.
28 public class FileCacheUtils {
30 private static final String FILES_CACHE = "FilesCache";
31 private static final int BUFFER_SIZE = 4096;
32 private static final long PROGRESS_UPDATE_RATE = 10;
33 private static final String TAG = FileCacheUtils.class.getSimpleName();
35 private FileCacheUtils() {
39 public static String getCachedFileForUrl(String url) {
40 File cachedFile = new File(getCurrentCachePath() + File.separator + url.hashCode());
41 if (cachedFile.exists()) {
42 return cachedFile.getAbsolutePath();
48 public static boolean deleteFileForUrl(String url) {
49 File cachedFile = new File(getCurrentCachePath() + File.separator + url.hashCode());
50 if (cachedFile.exists()) {
51 return cachedFile.delete();
53 Log.e(TAG, "There is no file to be removed: " + url);
58 public static boolean writeResponseBodyToDiskCache(ResponseBody body, String fileUrl) {
60 String cachePath = getCurrentCachePath();
61 File fileCacheDir = new File(cachePath);
62 File downloadFile = new File(cachePath + File.separator + fileUrl.hashCode() + ".download");
63 createCacheFolderAndFile(cachePath, fileCacheDir, downloadFile);
65 InputStream inputStream = null;
66 OutputStream outputStream = null;
69 byte[] fileReader = new byte[BUFFER_SIZE];
70 long fileSize = body.contentLength();
71 long fileSizeDownloaded = 0;
73 inputStream = body.byteStream();
74 outputStream = new FileOutputStream(downloadFile);
78 int read = inputStream.read(fileReader);
83 outputStream.write(fileReader, 0, read);
84 fileSizeDownloaded += read;
85 if (updateRate++ % PROGRESS_UPDATE_RATE == 0) {
86 EventBus.getDefault().post(new DownloadProgressEvent(fileUrl, fileSizeDownloaded, fileSize));
91 File audioFileDest = new File(cachePath + File.separator + fileUrl.hashCode());
92 boolean renamed = downloadFile.renameTo(audioFileDest);
94 throw new IOException("Failed to rename downloaded file: " + audioFileDest.getAbsolutePath());
97 } catch (IOException e) {
98 Log.e(TAG, "Failed to save file to cache: " + fileUrl, e);
99 downloadFile.delete();
102 if (inputStream != null) {
105 if (outputStream != null) {
106 outputStream.close();
109 } catch (IOException e) {
110 Log.e(TAG, "File creation or streaming closure failed", e);
115 private static void createCacheFolderAndFile(String cachePath, File audioCacheDir, File audioFile) throws IOException {
116 if (!audioCacheDir.exists()) {
117 boolean result = audioCacheDir.mkdir();
119 throw new IOException("Failed to create AudioCache Dir.");
122 if (!audioFile.exists()) {
123 boolean result = audioFile.createNewFile();
125 throw new IOException("Failed to create file in path: " + audioFile.getAbsolutePath());
131 private static String getCurrentCachePath() {
132 File externalCacheDir = WLApplication.getInstance().getApplicationContext().getExternalCacheDir();
133 String cachePath = (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !isExternalStorageRemovable()) &&
134 externalCacheDir != null ? externalCacheDir.getPath() : WLApplication.getInstance().getCacheDir().getPath();
135 return cachePath + File.separator + FILES_CACHE;
138 public static Completable deleteAudiobookFiles(List<String> fileUrls) {
139 return Completable.fromAction(() -> {
140 for (String fileUrl : fileUrls) {
141 boolean deleted = deleteFileForUrl(fileUrl);
143 Log.e(TAG, "Failed to delete file " + FileCacheUtils.getCachedFileForUrl(fileUrl));
149 public static Completable deleteEbookFile(final String epubUrl) {
150 return Completable.fromAction(() -> deleteFileForUrl(epubUrl));
154 * Event indicating progress.
156 public static class DownloadProgressEvent {
158 private String fileUrl;
159 private long downloaded;
162 public DownloadProgressEvent(String fileUrl, long downloaded, long total) {
163 this.fileUrl = fileUrl;
164 this.downloaded = downloaded;
168 public String getFileUrl() {
172 public long getDownloaded() {
176 public long getTotal() {